先看這張圖吧:
在這些類的調(diào)用過(guò)程中荡灾,尤其是在ActivityStack和ActivityStackStack這兩個(gè)類中都在頻繁的操控Activity的生命周期調(diào)度筷黔,
這個(gè)是Activity onCreate()的調(diào)度方法:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
results, newIntents, !andResume, mService.isNextTransitionForward(),
profilerInfo);
這個(gè)是 Activity onResume( ) 的調(diào)度方法:
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
mService.isNextTransitionForward(), resumeAnimOptions);
這里的app.thread到底是何方神圣鞠眉,為什么不直接操作Activity而是要通過(guò)這樣一個(gè)app.Thread(app.Thread并不是Thread)?
先認(rèn)識(shí)下這個(gè)Thread
/**
- System private API for communicating with the application. This is given to
- the activity manager by an application when it starts up, for the activity
- manager to tell the application about things it needs to do.
- {@hide}
*/
public interface IApplicationThread extends IInterface
其內(nèi)部包含了大量啟動(dòng),停止Activity的接口還包含了啟動(dòng)和停止服務(wù)的接口從命名可以看出路捧,IApplicationThread 這個(gè)Binder接口的實(shí)現(xiàn)者完成了大量的Activity以及Service啟動(dòng)/停止相關(guān)的功能淹真。
那我們就來(lái)看看IApplicationThread 的實(shí)現(xiàn)類:
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
雖然這個(gè)是抽象類讶迁,但是其中也做了相當(dāng)多的操作如:
class ApplicationThreadProxy implements IApplicationThread {
···
public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
Bundle resumeArgs)
throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(procState);
data.writeInt(isForward ? 1 : 0);
data.writeBundle(resumeArgs);
mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
···
}
沒錯(cuò),這就是系統(tǒng)為AIDL文件自動(dòng)生成的代理類核蘸。
ActivityThread有個(gè)內(nèi)部類ApplicationThread 巍糯,
private class ApplicationThread extends ApplicationThreadNative
最終回到了ApplicationThread 的 scheduleLaunchActivity()
// 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,
IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
···
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
沒啥難度,重點(diǎn)在最后一句客扎,發(fā)送一個(gè)啟動(dòng)Activity的消息給ActivityThread內(nèi)部的Handler祟峦;
哪里有handler?額徙鱼,它有個(gè)大方且?guī)洑獾拿郑?br>
private class H extends Handler
呵呵 宅楞, 我方了
看看我們的H干了點(diǎn)啥:
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;
這里只是等待處理完成后關(guān)閉trace,算是完成了一次進(jìn)程間通信袱吆,有讀取有回寫厌衙,相當(dāng)完美。
回到重點(diǎn):
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
···
//開啟activity的create之旅
Activity a = performLaunchActivity(r, customIntent);
//啟動(dòng)完畢接下來(lái)進(jìn)入onResume()
if (a != null) {
···
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
}
}
在這之前其實(shí)有個(gè)小小的疑問(wèn)绞绒,這時(shí)候Handler為什么可以調(diào)用婶希?(雖然我們是從startActivity開始,但是如果應(yīng)用剛剛開始蓬衡,這個(gè)ActivityThread一定會(huì)在App啟動(dòng)的時(shí)候悄悄搞點(diǎn)事情)而且拉風(fēng)的H竟然還掌控著Activity的生命周期喻杈,這個(gè)神奇的UIThread到底是什么時(shí)候,被誰(shuí)創(chuàng)建出來(lái)的呢狰晚?
答案在ApplicationInit()里:
ApplicationInit()除了設(shè)置虛擬機(jī)的兩個(gè)參數(shù)外筒饰,最重要的是調(diào)用了invokeStaticMain(args.startClass,args.startArgs),調(diào)用的參數(shù)args.startClass是通過(guò)socket傳入的壁晒,通常是“android.app.ActivityThread”這樣將會(huì)調(diào)用ActivityThread的main()方法瓷们。但是invokeStaticMain()并不是直接調(diào)用main()方法,而是拋出了一個(gè)Exception:
throw new ZygoteInit.MethodAndArgsCaller(m,argv);
在 ZygoteInit的mian()方法中會(huì)catch這個(gè)Exception:
catch (MethodAndArgsCaller caller){
caller.run();
}
這里為什么要先拋出一個(gè)Exception是因?yàn)閺腪ygoteInit調(diào)用開始到最終進(jìn)入invokeStaticMain()系統(tǒng)的棧里面已經(jīng)累積了不少調(diào)用幀,調(diào)用ActivityThread的mian()函數(shù)不會(huì)返回谬晕,為了能清除前面的調(diào)用棧幀式镐,給新運(yùn)行的應(yīng)用一個(gè)干凈的環(huán)境,才使用了throw Exception的方式固蚤。
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());
Security.addProvider(new AndroidKeyStoreProvider());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
//設(shè)置進(jìn)程名稱
Process.setArgV0("<pre-initialized>");
//初始化Looper
Looper.prepareMainLooper();
//創(chuàng)建ActivityThread
ActivityThread thread = new ActivityThread();
//通過(guò)False主動(dòng)調(diào)用attach
thread.attach(false);
if (sMainThreadHandler == null) {//保存主線程的Handler
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();//初始化AsyncTask類
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
看看ActivityThread 的 attach()都綁定了什么 :
private void attach(boolean system) {
···
if (!system) {
···
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
//把ApplicationThread對(duì)象放到RuntimeInit中
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//把ApplicationThread傳入AMS并調(diào)用AMS的attachApplication()
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
···
} else {
···
}
···
}
竟然推著ActivityManagerService也跟著動(dòng)了起來(lái):
attachApplication( ) -> attachApplicationLocked( ) ->ApplicationThread.bindApplication( )
這里bindApplication()會(huì)發(fā)送消息BIND_APPLICATION
private void handleBindApplication(AppBindData data)
這里主要作用就是創(chuàng)建應(yīng)用框架中的各種對(duì)象:
InstrumentationInfo
Instrumentation
ApplicationInfo
Application
LoadedApk
ContextImpl
···
->mStackSupervisor.attachApplicationLocked()->mStackSupervisor.realSrartActivityLocked( )
這個(gè)方法里做了判斷娘汞,如果進(jìn)程沒有啟動(dòng)則啟動(dòng)進(jìn)程,如果進(jìn)程啟動(dòng)了則調(diào)用Activity的onResume( )
最后用圖說(shuō)話(后來(lái)補(bǔ)上的):