ActivityThread分析—ActivityThread的main方法的执行流程分析
前言
前面我们分析了ActivityThread的main方法是如何被调用的,本篇我们来分析ActivityThread的main方法内的流程。
源码基于2.3,有错误还望指出。感谢。
代码分析
frameworks\base\core\java\android\app\ActivityThread.java#main()
public static final void main(String[] args) {SamplingProfilerIntegration.start();Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();// 1if (sMainThreadHandler == null) {sMainThreadHandler = new Handler();}ActivityThread thread = new ActivityThread();thread.attach(false);//3if (false) {Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));}Looper.loop();// 2if (Process.supportsProcesses()) {throw new RuntimeException("Main thread loop unexpectedly exited");}thread.detach();String name = (thread.mInitialApplication != null)? thread.mInitialApplication.getPackageName(): "<unknown>";Slog.i(TAG, "Main thread of " + name + " is now exiting");}
需要分析的为注释1,2,3处,1-2处是Handler-Looper消息循环的建立,着重看第3处。
frameworks\base\core\java\android\app\ActivityThread.java#attach()
参数boolean system,表示当前是否为系统线程。
1.这里为true时,进入到注释1处开始进行Application的创建(这里涉及到的Instrumentation本文暂不展开,等后面专门开篇讨论这个东西),并调用Application的baseAttach和onCreate方法,这里调用的地方是在ActivityThread的sysmain方法内调用的,我觉得这里就是启动Launcher的时候的流程,这不是重点,重点看注释2处,即ActivityThread的main内。
2.ActivityManagerNative.getDefault()
返回一个binder对象,这个实际上就是一个Ams实例,然后调用Ams的attachApplication方法。我们接着往下看代码。
private final void attach(boolean system) {sThreadLocal.set(this); // 0mSystemThread = system;if (!system) {......android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");RuntimeInit.setApplicationObject(mAppThread.asBinder()); IActivityManager mgr = ActivityManagerNative.getDefault(); //注释2.IActivityManager就是Binder,实际上是Amstry {mgr.attachApplication(mAppThread);//注释2.通过Binder与ApplicationThread关联} catch (RemoteException ex) {}} else {// Don't set application object here -- if the system crashes,// we can't display an alert, we just want to die die die.android.ddm.DdmHandleAppName.setAppName("system_process");try {mInstrumentation = new Instrumentation(); ContextImpl context = new ContextImpl();context.init(getSystemContext().mPackageInfo, null, this);Application app = Instrumentation.newApplication(Application.class, context);//注释1mAllApplications.add(app);mInitialApplication = app;app.onCreate();//Application的oncreate入口} catch (Exception e) {throw new RuntimeException("Unable to instantiate Application():" + e.toString(), e);}}ViewRoot.addConfigCallback(new ComponentCallbacks() { public void onConfigurationChanged(Configuration newConfig) {synchronized (mPackages) {// We need to apply this change to the resources// immediately, because upon returning the view// hierarchy will be informed about it.if (applyConfigurationToResourcesLocked(newConfig)) {// This actually changed the resources! Tell// everyone about it.if (mPendingConfiguration == null ||mPendingConfiguration.isOtherSeqNewer(newConfig)) {mPendingConfiguration = newConfig;queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);}}}}public void onLowMemory() {}});}
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java#attachApplication()
在注释1处调用了attachApplicationLocked方法,这里的参数thread是上一步传递过来的一个ApplicationThread对象。接着往下看。
public final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);// 1Binder.restoreCallingIdentity(origId);}}
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java#attachApplication()
这个方法忒长,略去其他代码,主要有2处比较重要:
1.注释1处,这里是调用了之前传递进来的ApplicationThread的bindApplication方法。这个主要是去绑定一些应用信息。
2.注释2处,这里就是真正的去打开一个Activity了,我们先分析注释1,再分析注释2.
接下来我们点进注释1的方法内。
private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {// Find the application record that is being attached... either via// the pid if we are running in multiple processes, or just pull the// next app record if we are emulating process with anonymous threads.......// If this application record is still attached to a previous// process, clean it up now.......// Tell the process all about itself.......if (localLOGV) Slog.v(TAG, "New app record "<