源码分析 -- ActivityThread
来源:互联网 发布:淘宝网天猫女装外套 编辑:程序博客网 时间:2024/06/06 01:55
1. ActivityThread功能
它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求负责调度和执行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
如果不单独创建子线程,一个应用包含以下的线程,是系统自动创建的
并不是只有一个main主线程。具体看系统应用的启动流程分析
这些线程运行在不同的进程中,除了main,都是系统进程
应用程序所在的进程中只有main这一个线程
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)
也就是android的应用进程的入口是ActivityThread,而不是Application.
ActivityThread是主线程,会有个Handler处理消息。
消息处理函数定义如下:
- public void handleMessage(Message msg) {
- switch (msg.what) {
- // 这里收到消息以后才会反射创建Applicationd 的对象
- case BIND_APPLICATION: // 创建Application对象
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
- AppBindData data = (AppBindData)msg.obj;
- handleBindApplication(data);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
3. IApplicationThread关系图
ApplicationThread类是ActivitiyThread的内部类
private class ApplicationThread extends ApplicationThreadNative {
// 实现了以下的方法,具体看下面源码分析
schedulePauseActivity
scheduleLaunchActivity
}
4. ActivityThread类
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(); // 定义的内部类,Handler子类,用于处理消息
- 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;
- ...
- }
- // ApplicationThread继承自ApplicationThreadNative, 而ApplicationThreadNative又继承自Binder并实现了IApplicationThread接口。IApplicationThread继承自IInterface。这是一个很明显的binder结构,用于Ams通信。IApplicationThread接口定义了对一个程序(linux的进程)操作的接口。ApplicationThread通过binder与Ams通信,并将Ams的调用,通过下面的H类(也就是Hnalder)将消息发送到消息队列,然后进行相应的操作,入activity的start, stop。
- private class ApplicationThread extends ApplicationThreadNative {
- private void updatePendingConfiguration(Configuration config) {
- synchronized (mPackages) {
- if (mPendingConfiguration == null ||
- mPendingConfiguration.isOtherSeqNewer(config)) {
- mPendingConfiguration = config;
- }
- }
- }
- // 给主消息队列发送消息,处理暂停事件
- // 这些方法是在IApplicationThread接口定义的方法,由ApplicationThread这个类实现。应该是由Ams回调的。
- 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)
- // startActivity流程中就是调用的这个函数,应该是由AMs调用的。具体的调用时机看AMS的内容
- 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);
- // 往消息队列发送一个消息LAUNCH_ACTIVITY。启动activity.
- 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);
- // 对应activity的启动流程,这里面才会反射创建activity的对象和进行初始化,调用onCreate方法
- 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 libcore
- EventLogger.setReporter(new EventLoggingReporter());
- Process.setArgV0("<pre-initialized>");
-
- Looper.prepareMainLooper(); //我们都知道主线程可以使用Handler进行异步通信,因为主线程中已经创建了Looper,而这个Looper就是在这里创建的。如果其他线程需要使用Handler通信,就要自己去创建Looper。
- // 创建ActivityThread实例
- ActivityThread thread = new ActivityThread();
- thread.attach(false);
- if (sMainThreadHandler == null) {
- sMainThreadHandler = thread.getHandler();
- }
- AsyncTask.init();
- if (false) {
- Looper.myLooper().setMessageLogging(new
- LogPrinter(Log.DEBUG, "ActivityThread"));
- }
- Looper.loop(); // 进入消息循环
- throw new RuntimeException("Main thread loop unexpectedly exited");
- }
- }
4.2 家族图谱
http://blog.csdn.net/gaowenboms/article/details/8815163- ActivityThread源码分析
- 源码分析 -- ActivityThread
- ActivityThread分析
- ActivityThread分析
- ActivityThread 源码笔记(1)
- ActivityThread.java源码
- ActivityThread启动源码解析
- (1)ActivityThread分析
- ActivityThread-activity启动分析
- ActivityThread-activity启动分析
- (1)ActivityThread分析
- (1)ActivityThread分析
- (1)ActivityThread分析
- Activity启动分析(一)--ActivityThread
- ActivityThread
- ActivityThread
- 系统入门(7):ActivityThread分析
- 一道面试题引发的对android中context的研究(三)-各种Context在ActivityThread中实例化过程源码分析
- hihoCoder 1288
- Java IO : InputStream、Reader
- app更新前注意的地方
- 用C++实现简易的文本编辑器
- 我的坎坷科研之路
- 源码分析 -- ActivityThread
- #151 – Dependency Properties Remember Non-Coerced Values(依赖属性强制转换之前的值会被记住)
- 通信组件之Intent的基本使用
- UILable显示不同的字体颜色、字体大小、行间距、首行缩进、下划线等属性(NSMutableAttributedString)
- Node.js: managing child processes
- java线程同步锁
- iOS po 命令打印视图层极
- IOS自动化测试之UIAutomation学习
- Mac下zookeeper启动失败/zookeeper_server.pid:Permission denied