1. ActivityThread功能

它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IApplicationThread接口,AMS为Client、ActivityThread.ApplicationThread为Server)负责调度和执行activities、broadcasts和其它操作。

在Android系统中,在默认情况下,一个应用程序内的各个组件(如Activity、BroadcastReceiver、Service)都会在同一个进程(Process)里执行,且由此进程的【主线程】负责执行。

在Android系统中,如果有特别指定(通过android:process),也可以让特定组件在不同的进程中运行。无论组件在哪一个进程中运行,默认情况下,他们都由此进程的【主线程】负责执行。

【主线程】既要处理Activity组件的UI事件,又要处理Service后台服务工作,通常会忙不过来。为了解决此问题,主线程可以创建多个子线程来处理后台服务工作,而本身专心处理UI画面的事件。

【主线程】的主要责任:

• 快速处理UI事件。而且只有它才处理UI事件, 其它线程还不能存取UI画面上的对象(如TextView等),此时, 主线程就叫做UI线程。基本上,Android希望UI线程能根据用户的要求做出快速响应,如果UI线程花太多时间处理后台的工作,当UI事件发生时,让用户等待时间超过5秒而未处理,Android系统就会给用户显示ANR提示信息。

只有UI线程才能执行View派生类的onDraw()函数。

• 快速处理Broadcast消息。【主线程】除了处理UI事件之外,还要处理Broadcast消息。所以在BroadcastReceiver的onReceive()函数中,不宜占用太长的时间,否则导致【主线程】无法处理其它的Broadcast消息或UI事件。如果占用时间超过10秒, Android系统就会给用户显示ANR提示信息。

注意事项:

尽量避免让【主线程】执行耗时的操作,让它能快速处理UI事件和Broadcast消息。

BroadcastReceiver的子类都是无状态的,即每次启动时,才会创建其对象,然后调用它的onReceive()函数,当执行完onReceive()函数时,就立即删除此对象。由于每次调用其函数时,会重新创建一个新的对象,所以对象里的属性值,是无法让各函数所共享。

1.1 Thread与SurfaceView

View组件由UI线程(主线程)所执行。如果需要迅速更新UI画面或UI画图需要较长时间,则需要使用SurfaceView。它可由后台线程(background thread)来执行,而View只能由UI(主)线程执行。SurfaceView内有高效的rendering机制,可以让后台线程快速刷新Surface的内容。

View ---> UI(主)线程

SurfaceView ---> 后台线程

2. Android应用程序主线程stack

在一个只有Activity派生类的应用程序中,它包含如下线程:

main线程stack如下:

  at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:118)  at android.os.Looper.loop(Looper.java:118)  at android.app.ActivityThread.main(ActivityThread.java:4424)    // Java main入口函数at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method)    

JDWP线程stack如下:

  at org.apache.harmony.dalvik.ddmc.DdmVmInternal.getStackTraceById(Native Method) at android.ddm.DdmHandleThread.handleSTKL(DdmHandleThread.java:131) at android.ddm.DdmHandleThread.handleChunk(DdmHandleThread.java:77) at org.apache.harmony.dalvik.ddmc.DdmServer.dispatch(DdmServer.java:171)    at dalvik.system.NativeStart.run(Native Method)

3. IApplicationThread关系图

4. ActivityThread类

ActivityThread类即代表Application主线程。

4.1 类中关键信息

/*** This manages the execution of the main thread in an* application process, scheduling and executing activities,* broadcasts, and other operations on it as the activity* manager requests.** {@hide}*/
public final class ActivityThread {static ContextImpl mSystemContext = null;static IPackageManager sPackageManager;// 创建ApplicationThread实例,以接收AMS指令并执行final ApplicationThread mAppThread = new ApplicationThread();final Looper mLooper = Looper.myLooper();final H mH = new H();final HashMap<IBinder, ActivityClientRecord> mActivities= new HashMap<IBinder, ActivityClientRecord>();// List of new activities (via ActivityRecord.nextIdle) that should// be reported when next we idle.ActivityClientRecord mNewActivities = null;// Number of activities that are currently visible on-screen.int mNumVisibleActivities = 0;final HashMap<IBinder, Service> mServices= new HashMap<IBinder, Service>();Application mInitialApplication;final ArrayList<Application> mAllApplications= new ArrayList<Application>();static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();Instrumentation mInstrumentation;static Handler sMainThreadHandler;  // set once in main()static final class ActivityClientRecord {IBinder token;int ident;Intent intent;Bundle state;Activity activity;Window window;Activity parent;String embeddedID;Activity.NonConfigurationInstances lastNonConfigurationInstances;boolean paused;boolean stopped;boolean hideForNow;Configuration newConfig;Configuration createdConfig;ActivityClientRecord nextIdle;String profileFile;ParcelFileDescriptor profileFd;boolean autoStopProfiler;ActivityInfo activityInfo;CompatibilityInfo compatInfo;LoadedApk packageInfo; //包信息,通过调用ActivityThread.getPapckageInfo而获得List<ResultInfo> pendingResults;List<Intent> pendingIntents;boolean startsNotResumed;boolean isForward;int pendingConfigChanges;boolean onlyLocalRequest;View mPendingRemoveWindow;WindowManager mPendingRemoveWindowManager;...}private class ApplicationThread extends ApplicationThreadNative {private void updatePendingConfiguration(Configuration config) {synchronized (mPackages) {if (mPendingConfiguration == null ||mPendingConfiguration.isOtherSeqNewer(config)) {mPendingConfiguration = config;}}}public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges) {queueOrSendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,token,(userLeaving ? 1 : 0),configChanges);}// we use token to identify this activity without having to send the// activity itself back to the activity manager. (matters more with ipc)public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,Bundle state, List<ResultInfo> pendingResults,List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {ActivityClientRecord r = new ActivityClientRecord();r.token = token;r.ident = ident;r.intent = intent;r.activityInfo = info;r.compatInfo = compatInfo;r.state = state;r.pendingResults = pendingResults;r.pendingIntents = pendingNewIntents;r.startsNotResumed = notResumed;r.isForward = isForward;r.profileFile = profileName;r.profileFd = profileFd;r.autoStopProfiler = autoStopProfiler;updatePendingConfiguration(curConfig);queueOrSendMessage(H.LAUNCH_ACTIVITY, r);}...}private class H extends Handler {public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));switch (msg.what) {case LAUNCH_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");ActivityClientRecord r = (ActivityClientRecord)msg.obj;r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);handleLaunchActivity(r, null);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;...}if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));}...}public static ActivityThread currentActivityThread() {return sThreadLocal.get();}public static void main(String[] args) {SamplingProfilerIntegration.start();// CloseGuard defaults to true and can be quite spammy.  We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();// 创建ActivityThread实例ActivityThread thread = new ActivityThread();thread.attach(false);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}AsyncTask.init();if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}
}

4.2 家族图谱

4.3 ActivityThread内部类

4.4 ActivityThread工作流程

Android ActivityThread(主线程或UI线程)简介相关推荐

  1. C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它...

    C# 委托 / 跨线程访问UI /  线程间操作无效: 从不是创建控件"Form1"的线程访问它 网上的代码都比较复杂,还是这个简单 见代码, 简易解决办法: 主窗体代码 usin ...

  2. Android基础知识:在UI线程中运行代码

    本文翻译自:Android basics: running code in the UI thread In the viewpoint of running code in the UI threa ...

  3. android 异步回调中操作UI线程,UI同步、卡死阻塞等性能问题

    android开发中,回调无处不在,整个android开发的框架就是以回调机制建立起来的.如:activity,service,broadcast,fragment,view事件监听,baseadap ...

  4. 技术派-在工作线程与UI线程中创建对话框

    目录 UI线程创建方式 头文件模板 实现代码模板 工作线程的创建方式 工作线程的线程模板 对话框头文件模板 对话框实现部分 我们在工作中,经常需要在新线程里面创建对话框,要么是在工作线程里面创建对话框 ...

  5. 在Adapter里子线程更新UI线程

    代码: ((Activity)context).runOnUiThread(new Runnable() {@Overridepublic void run() {holder.mIvPlay.set ...

  6. android 组件 线程,Android UI线程和非UI线程

    UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这个主线程里,你的应用和Android的 ...

  7. Android UI线程和非UI线程

    UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这个主线程里,你的应用和Android的 ...

  8. 理解UI线程——SWT, Android, 和Swing的UI机理

    2019独角兽企业重金招聘Python工程师标准>>> 在做GUI的时候, 无论是SWT, AWT, Swing 还是Android, 都需要面对UI线程的问题, UI线程往往会被单 ...

  9. android中多线程与ui,Android UI线程和非UI线程

    UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程. 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这个主线程里,你的应用和Android的UI组件发生交互. 所以主 ...

最新文章

  1. 【Android FFMPEG 开发】Android 中使用 FFMPEG 对 MP3 文件进行混音操作
  2. POJ 1088(滑雪)
  3. leetcode 677. Map Sum Pairs | 677. 键值映射(Trie前缀树,BFS)
  4. halcon区域腐蚀膨胀算子_Halcon 形态学膨胀腐蚀应用举例
  5. SpringBoot 实现热部署有哪几种方式
  6. SVN仓库安装、备份和迁移基本操作
  7. YUM命令常见报错以及解决办法
  8. FTP Client Setup
  9. VScode C、c++ 环境(windows10 17763.1131)
  10. SQLyog之MySQL客户端的下载、安装和使用(普通版)
  11. AD21怎么打印丝印层的PDF
  12. 浅浅总结一下HTML吧
  13. RRStudio(一)
  14. U盘安装Win Server 2008
  15. 网络传真和传真服务器
  16. 自己实现一个Spring 框架
  17. Interview Vocabulary Summary
  18. 多张图片怎么统一修改尺寸?
  19. 携创教育:2022年10月自考英语二高分技巧有哪些?
  20. 七牛云 上传图片到七牛云并返回图片URL

热门文章

  1. Git: windows系统下如何设置git的默认文本编辑软件
  2. Unity(新机)安装失败解决办法
  3. Python进阶----pymysql模块的使用,单表查询
  4. Java+MySQL基于ssm的车辆违章管理系统
  5. 打开catia界面全是白色怎么办_英雄联盟提示对局仍在进行中进不去游戏怎么办...
  6. Adobe Photoshop CC 2019画板背景色白底如何去掉?
  7. 高并发核心编程Spring Cloud+Nginx秒杀实战,秒杀业务的参考实现
  8. SQL中的模糊查询like
  9. 计算机显卡性价比推荐,电脑显卡性价比排行2019 玩游戏显卡什么牌子好
  10. 小学计算机室均衡解说词,迎接县均衡化国家验收学校解说词(2017.11.14)