繼上篇文章Launcher進程的啟動,我們繼續(xù)分析Home界面的啟動,
Home界面的啟動
。public final class ActivityThread { ...... public static final void main(String[] args) { SamplingProfilerIntegration.start(); Process.setArgV0(thread.attach函數(shù)如下: private final void attach(boolean system) { sThreadLocal.set(this); mSystemThread = system; if (!system) { ...... IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { } } else { ...... } ......}static public IActivityManager getDefault() { if (gDefault != null) { //if (Config.LOGV) Log.v( // ActivityManager, returning cur default = + gDefault); return gDefault; } IBinder b = ServiceManager.getService(activity); if (Config.LOGV) Log.v( ActivityManager, default service binder = + b); gDefault = asInterface(b); if (Config.LOGV) Log.v( ActivityManager, default service = + gDefault); return gDefault; }static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ActivityManagerProxy(obj); }在ActivityThread類的成員函數(shù)attach中,調用ActivityManagerNative類的靜態(tài)成員函數(shù)getDefault來獲得ActivityMangerService的一個代理對象,代理對象的類型為ActivityMangerProxy。
mgr.attachApplication(mAppThread)實際上調用的是ActivityManagerProxy的attachApplication,如下:
class ActivityManagerProxy implements IActivityManager{ public void attachApplication(IApplicationThread app) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); } ......}其中app為:final ApplicationThread mAppThread = new ApplicationThread();繼承于ApplicationThreadNative,ApplicationThreadNative繼承于Binder實現(xiàn)了IApplicationThread。由于是同步傳輸,所以Launcher進程主線程睡眠等待。
此時System進程Binder主線程池和子線程池都開啟了,正在等待來自Launcher進程的請求。
System進程,接收到請求后,如上圖的Binder進程間通信的省略步驟一樣,會執(zhí)行如下代碼:
public abstract class ActivityManagerNative extends Binder implements IActivityManager{ ...... public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case ATTACH_APPLICATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IApplicationThread app = ApplicationThreadNative.asInterface( data.readStrongBinder()); if (app != null) { attachApplication(app); } reply.writeNoException(); return true; } .......}首先生成BinderProxy對象,里面的mObject指向代理對象,向上轉型為IBinder。然后生成ApplicationThreadProxy對象,里面mRemote指向BinderProxy對象。
由于ActivityManagerService類繼承于ActivityManagerNative類,所以attachApplication,實際上執(zhí)行的是位于ActivityManagerService中的。
public final class ActivityManagerService extends ActivityManagerNative{ public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long rigId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } } .....}這里將操作轉發(fā)給attachApplicationLocked函數(shù),如下:public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... 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. ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid);//取回ProcessRecord對象,保存在app中,app就是用來描述新創(chuàng)建的應用程序進程的 } } else if (mStartingProcesses.size() > 0) { ...... } else { ...... } if (app == null) { ...... return false; } ...... String processName = app.processName; try { thread.asBinder().linkToDeath(new AppDeathRecipient( app, pid, thread), 0); } catch (RemoteException e) { ...... return false; } ...... app.thread = thread;//thread設置為參數(shù)thread所指向的一個ApplicationThread代理對象 ...... mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);//刪除ActivityMangerService所運行在的線程的消息隊列中PROC_START_TIMEOUT_MSG消息 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); ...... boolean badApp = false; boolean didSomething = false; // See if the top visible activity is waiting to run in this process... ActivityRecord hr = mMainStack.topRunningActivityLocked(null);//位于棧頂?shù)腁ctivityRecord是Home界面的ActivityRecord if (hr != null && normalMode) { if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) { try { if (mMainStack.realStartActivityLocked(hr, app, true, true)) {//最后走這里 didSomething = true; } } catch (Exception e) { ...... } } else { ...... } } ...... return true; } ......}在System進程的啟動流程第二部分,最后一部分,ActivityManager以這個PID為關鍵字將一個ProcessRecord對象保存在了成員變量mPidsSelfLocked中。所以首先通過參數(shù)pid將這個ProcessRecord對象取回來,并且保存在app中。然后對app初始化,其中最重要的是將它的成員變量thread設置為參數(shù)thread所指向的一個ApplicationThread代理對象。這樣,ActivityManagerService以后就可以通過這個ApplicationThread代理對象來和新創(chuàng)建的應用程序進程進行通信了。
還記得在System進程的啟動流程第二部分,最后一部分,會向ActivityManagerService所運行的線程的消息隊列發(fā)送一個類型為PROC_START_TIMEOUT_MSG的消息,并且指定這個消息在PROC_START_TIMEOUT毫秒之后處理。
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); msg.obj = app; mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);這里通過以下代碼來刪除ActivityMangerService所運行在的線程的消息隊列中PROC_START_TIMEOUT_MSG消息,因為新的應用程序進程已經(jīng)在規(guī)定的時間內啟動起來了。
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app)最后通過ActivityStack類的成員函數(shù)realStartActivityLocked來請求該應用程序進程啟動一個Activity。public class ActivityStack { ...... final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ...... r.app = app;//r的成員變量app的值設置為參數(shù)app,表示它描述的Activity組件是在參數(shù)app所描述的應用程序進程中啟動的 ...... int idx = app.activities.indexOf(r); if (idx < 0) { app.activities.add(r);//將該Activity添加到參數(shù)app所描述的應用程序進程的Activity組件列表中 } ...... try { ...... List<resultinfo>results = null; List<intent>newIntents = null; if (andResume) { results = r.results; newIntents = r.newIntents; } ...... app.thread.scheduleLaunchActivity(new Intent(r.intent), r, System.identityHashCode(r), r.info, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward()); ...... } catch (RemoteException e) { ...... } ...... return true; } ......}</intent></resultinfo>這里最終通過app.thread進入到ApplicationThreadProxy的scheduleLaunchActivity函數(shù)中,注意,這里的第二個參數(shù)r,是一個ActivityRecord類型的Binder對象,用來作來這個Activity的token值,
電腦資料
《Home界面的啟動》(http://m.clearvueentertainment.com)。public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Bundle state, List<resultinfo>pendingResults, List<intent>pendingNewIntents, boolean notResumed, boolean isForward) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); intent.writeToParcel(data, 0); data.writeStrongBinder(token); data.writeInt(ident); info.writeToParcel(data, 0); data.writeBundle(state); data.writeTypedList(pendingResults); data.writeTypedList(pendingNewIntents); data.writeInt(notResumed ? 1 : 0); data.writeInt(isForward ? 1 : 0); mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); }</intent></resultinfo>其Binder類圖如下:
我們傳遞的數(shù)據(jù)token,是一個ActivityRecord類型的Binder對象,如下圖:
1、由于是異步傳輸,System進程傳輸完數(shù)據(jù)后,又開始在線程池繼續(xù)等待了。
2、 同時Launcher進程的主線程也該收到System進程返回的數(shù)據(jù)了,它還一直等待在如下代碼:
class ActivityManagerProxy implements IActivityManager{ public void attachApplication(IApplicationThread app) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); } ......}2、Launcher進程的主線程被喚醒后,繼續(xù)運行,會返回到ActivityThread的main函數(shù),執(zhí)行Looper.loop(),這樣Launcher進程的主線程的消息循環(huán)機制就創(chuàng)立了。3、由于Launcher進程子線程池已經(jīng)建立,并且在睡眠等待,此時發(fā)送數(shù)據(jù),會喚醒Launcher進程子線程,如Binder類圖所示,開始執(zhí)行如下代碼:
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread { ........ public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); Intent intent = Intent.CREATOR.createFromParcel(data); IBinder b = data.readStrongBinder(); int ident = data.readInt(); ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data); Bundle state = data.readBundle(); List<resultinfo>ri = data.createTypedArrayList(ResultInfo.CREATOR); List<intent>pi = data.createTypedArrayList(Intent.CREATOR); boolean notResumed = data.readInt() != 0; boolean isForward = data.readInt() != 0; scheduleLaunchActivity(intent, b, ident, info, state, ri, pi, notResumed, isForward); return true; } .....}</intent></resultinfo>其中b為一個BinderProxy的Binder代理對象,指向了ActivityManagerService中與Launcher進程對應的一個AcitivityRecord對象,如上圖所示。由于ApplicationThread繼承于ApplicationThreadNative,所以真正執(zhí)行的是ApplicationThread里面的scheduleLaunchActivity方法。
public final class ActivityThread { ...... private final class ApplicationThread extends ApplicationThreadNative { ...... // 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, Bundle state, List<resultinfo>pendingResults, List<intent>pendingNewIntents, boolean notResumed, boolean isForward) { ActivityClientRecord r = new ActivityClientRecord(); r.token = token; r.ident = ident; r.intent = intent; r.activityInfo = info; r.state = state; r.pendingResults = pendingResults; r.pendingIntents = pendingNewIntents; r.startsNotResumed = notResumed; r.isForward = isForward; queueOrSendMessage(H.LAUNCH_ACTIVITY, r); } ...... } ......}</intent></resultinfo>函數(shù)首先創(chuàng)建一個ActivityClientRecord實例,并且初始化它的成員變量,然后調用ActivityThread類的queueOrSendMessage函數(shù)進一步處理。
public final class ActivityThread { ...... private final class ApplicationThread extends ApplicationThreadNative { ...... // if the thread hasn't started yet, we don't have the handler, so just // save the messages until we're ready. private final void queueOrSendMessage(int what, Object obj) { queueOrSendMessage(what, obj, 0, 0); } ...... private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) { synchronized (this) { ...... Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; mH.sendMessage(msg); } } ...... } ......}由于目前是在Binder子線程池中處理的請求,所以queueOrSendMessage目前處于子線程,大家知道m(xù)H是主線程中Handler,剛剛完成了Loop.loop()進入了消息循環(huán)。public final class ActivityThread { ...... private final class H extends Handler { ...... public void handleMessage(Message msg) { ...... switch (msg.what) { case LAUNCH_ACTIVITY: { ActivityClientRecord r = (ActivityClientRecord)msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo); handleLaunchActivity(r, null); } break; ...... } ...... } ......}這里最后調用ActivityThread類的handleLaunchActivity函數(shù)進一步處理。public final class ActivityThread { ...... private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...... Activity a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle ldState = r.state; handleResumeActivity(r.token, false, r.isForward); ...... } else { ...... } } ......}這里首先調用performLaunchActivity函數(shù)來加載這個Activity類,即Home界面Activity,然后調用它的onCreate函數(shù),最后回到handleLaunchActivity函數(shù)時,再調用handleResumeActivity函數(shù)來使這個Activity進入Resumed狀態(tài),即會調用這個Activity的onResume函數(shù),這是遵循Activity的生命周期的。public final class ActivityThread { ...... private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...... ComponentName component = r.intent.getComponent(); ...... Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ...... } catch (Exception e) { ...... } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); ...... if (activity != null) { ContextImpl appContext = new ContextImpl(); appContext.init(r.packageInfo, r.token, this); appContext.setOuterContext(activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mConfiguration); ...... activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstance, r.lastNonConfigurationChildInstances, config); ....... mInstrumentation.callActivityOnCreate(activity, r.state); ...... } ...... mActivities.put(r.token, r); } catch (SuperNotCalledException e) { ...... } catch (Exception e) { ...... } return activity; } ......}這樣,就開始執(zhí)行Home界面的onCreate。1、至此,Launcher進程Binder子線程池在給主線程發(fā)送消息后,又進入睡眠等待狀態(tài)。onCreate是通過消息機制,在主線程中執(zhí)行的。
2、System進程又在線程池(主線程和子線程)繼續(xù)等待了。
3、Zygote進程等待連接請求,創(chuàng)建新的應用程序進程。