Android ActivityThread APP启动过程 详解Android中的ActivityThread和APP启动过程
小河同学 人气:1ActiviryThread
ActivityThread的初始化
ActivityThread即Android的主线程,也就是UI线程,ActivityThread的main方法是一个APP的真正入口,MainLooper在它的main方法中被创建。
//ActivityThread的main方法 public static void main(String[] args) { ... Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); //在attach方法中会完成Application对象的初始化,然后调用Application的onCreate()方法 thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } ... Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
接下来从主线程Looper的初始化和ApplicationThread及Activity的创建启动两方面,通过源码了解学习下大致的流程。
主线程Looper的初始化
Looper.prepareMainLooper();相关的代码如下
//主线程Looper的初始化 public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } //普通线程Looper的初始化 public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
看过Handler源码就知道,主线程Looper的初始化和普通线程Looper的初始化很相似,但还是有以下几个区别
1.普通线程的Prepare()默认quitAllowed参数为true,表示允许退出,而主线程也就是ActivityThread的Looper参数为false,不允许退出。这里的quitAllowed参数,最终会传递给MessageQueue,当调用MessageQueue的quit方法时,会判断这个参数,如果是主线程,也就是quitAllowed参数为false时,会抛出异常。
//Looper的退时会判断quitAllowed void quit(boolean safe) { if (!mQuitAllowed) { throw new IllegalStateException("Main thread not allowed to quit."); } synchronized (this) { ... } }
2.我们注意到主线程Looper初始化之后,赋值给了成员变量sMainLooper,这个成员的作用就是向其他线程提供主线程的Looper对象。这下我们就应该知道为什么Looper.getMainLooper()方法能获取主线程的Looper对象了
public static Looper getMainLooper() { synchronized (Looper.class) { return sMainLooper; } }
主线程Handler的初始化
在ActivityThread的main方法中我们注意到一行代码:
ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); }
见名知意,这是获取主线程的Handler,那么主线程的Handler是在什么时候初始化的呢?
//与之相关的代码如下: //ActivityThread的成员变量 final H mH = new H(); final Handler getHandler() { return mH; }
从以上代码中可以看到,主线程的Handler作为ActivityThread的成员变量,是在ActivityThread的main方法被执行,ActivityThread被创建时而初始化,而接下来要说的ApplicationThread中的方法执行以及Activity的创建都依赖于主线程Handler。至此我们也就明白了,主线程(ActivityThread)的初始化是在它的main方法中,主线程的Handler以及MainLooper的初始化时机都是在ActivityThread创建的时候。
ApplicationThread及Activity的创建和启动
以上的代码和流程,就是对 MainLooper 和 ActivityThread 的初始化,我们接下来看一下 ActivityThread 的初始化及其对应的 attach 方法,在thread.attach方法中,ActivityManagerService通过attachApplication方法,将ApplicationThread对象绑定到ActivityManagerService,ApplicationThread是ActivityThread的私有内部类,实现了IBinder接口,用于ActivityThread和ActivityManagerService的所在进程间通信。
//ActivityThread的attach方法: private void attach(boolean system) { ... if (!system) { final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); }else{ ... } } } //ActivityManagerService中的方法: public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }
这里的个人理解是:在每个ActivityThread(APP)被创建的时候,都需要向ActivityManagerService绑定(或者说是向远程服务AMS注册自己),用于AMS管理ActivityThread中的所有四大组件的生命周期。
上述AMS的代码中attachApplicationLocked方法比较复杂,主要功能有两个,详见注释,这里忽略了很多代码细节,具体的流程可以看源码
//AMS中的方法,主要功能有以下两步 private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ... //主要用于创建Application,用调用onCreate方法 thread.bindApplication(...); ... //主要用于创建Activity if (mStackSupervisor.attachApplicationLocked(app)) { ... } }
1.thread.bindApplication:主要用于创建Application,这里的thread对象是ApplicationThread在AMS中的代理对象,所以这里的bindApplication方法最终会调用ApplicationThread.bindApplication()方法,该方法会向ActivityThread的消息对应发送BIND_APPLICATION的消息,消息的处理最终会调用Application.onCreate()方法,这也说明Application.onCreate()方法的执行时机比任何Activity.onCreate()方法都早。
//ActivityThread中的bindApplication方法 public final void bindApplication(...) { ... // 该消息的处理,会调用handleBindApplication方法 sendMessage(H.BIND_APPLICATION, data); } //ActivityThread中的handleBindApplication方法 private void handleBindApplication(AppBindData data) { ... try { Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; ... try { mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { } } finally { } } //LoadedApk中的方法,用于创建Application public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { //如果存在Application的实例,则直接返回,这也说明Application是个单例 if (mApplication != null) { return mApplication; } Application app = null; //...这里通过反射初始化Application if (instrumentation != null) { try { //调用Application的onCreate方法 instrumentation.callApplicationOnCreate(app); } catch (Exception e) { } } return app; }
2.mStackSupervisor.attachApplicationLocked(app):用于创建Activity,mStackSupervisor是AMS的成员变量,为Activity堆栈管理辅助类实例,该方法最终会调用ApplicationThread类的scheduleLaunchActivity方法,该方法也是类似于第一步,向ActivityThread的消息队列发送创建Activity的消息,最终在ActivityThread中完成创建Activity的操作。
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { ... if (realStartActivityLocked(hr, app, true, true)) { ... } ... } final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ... try { //调用ApplicationThread的scheduleLaunchActivity用于启动一个Activity app.thread.scheduleLaunchActivity(...); } catch (RemoteException e) { } }
ApplicationThread的scheduleLaunchActivity方法会向ActivityThread发送LAUNCH_ACTIVITY信息,用于启动一个Activity,该消息的处理会调用ActivityThread的handleLaunchActivity方法,最终启动一个Activity
加载全部内容