基于Android11-API30
總覽
- 獲取applicationThread,AMS這兩個Binder
2.attach時,將獲取applicationThread物件也傳遞到AMS行程,請求遠程呼叫通知AMS應用行程想要創建Application,此時AMS為服務端 - AMS收到訊息,請求呼叫applicationThread的遠程介面,此時AMS為客戶端
- applicationThread收到AMS的請求,通過Handler發起創建Application的處理任務,后面就沒有遠程介面呼叫了
- 通過反射創建Application的實體,通過Instrumentation啟動Application的onCreate方法
詳細流程分析
從 ActivityThread.java 的main方法開始看;
public static void main(String[] args) {
...
ActivityThread thread = new ActivityThread();
thread.attach(system=false, startSeq);//1
...
}
進入attach方法;
if(!system){
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);//1
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
非系統應用流程,根據 getSeervice和捕獲的RemoteException可以斷定,此處在使用Binder進行遠程介面呼叫,
轉身看下mAppThread是什么?
final ApplicationThread mAppThread = new ApplicationThread();
private class ApplicationThread extends IApplicationThread.Stub {
//批量的schedule*介面,比如scheduleReceiver、scheduleCreateService等
public final void schedule*
//TODO 關鍵方法
public final void bindApplication(some args){}//1
//一堆dump方法,比如dumpMemory、dumpActivity等
}
可以看到,ApplicationThread是一個實作了遠程介面的Binder客戶端,內部封裝實作了很多遠程介面,不過這個客戶端什么時候連接的服務器還未可知,沒有找到bindService關鍵字,反正此時應該已經連接上對應的Service了,應該是在RuntimeInit.java類中進行應用行程啟動時啟動的,
回來看下前一步服務的實體IActivityManager.attachApplication()內部的實作,
- 先獲取AMS的實體,此處獲取AMS實體代碼跟Activity啟動流程中一致
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
…獲取到AMS的Binder后,繼續查看ActivityManagerService.java中的attachApplication方法
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq); //1
Binder.restoreCallingIdentity(origId);
}
}
單例獲取AMS實體,AMS服務在系統啟動就已經注冊到ServiceManager了,此處直接去獲取Binder實體就行,ServiceManager以Binder池的方式管理注冊的Server,
AMS的attachApplication方法中進入到attachApplicationLocked方法,撿能看懂的代碼看,跟著thread引數查看代碼,
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);//1
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
mProcessList.startProcessLocked(app,
new HostingRecord("link fail", processName),
ZYGOTE_POLICY_FLAG_EMPTY);
return false;
}
final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
if (instr2 != null) {//2
thread.bindApplication(processName, appInfo, providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.mDisabledCompatChanges);
} else {
thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.mDisabledCompatChanges);
}
}
先給ApplicationThread這個Binder上個死亡代理,根據這個死亡代理應該可以找到對應的Service是如何重新啟動的,感興趣可以繼續深入,咱們繼續往下走,
此處呼叫到thread.bindApplication介面,前面咱們查看ApplicationThread時有看到,直接切入,
private class ApplicationThread extends IApplicationThread.Stub {
//批量的schedule*介面,比如scheduleReceiver、scheduleCreateService等
public final void schedule*
//TODO 關鍵方法
public final void bindApplication(some args){
AppBindData data = new AppBindData();
...一堆引數
sendMessage(H.BIND_APPLICATION, data);//1
}
//一堆dump方法,比如dumpMemory、dumpActivity等
}
到達咱們Android開發工程師比較熟悉的點了,封裝了一堆引數后,通過H這個Handler物件發了一條BIND_APPLICATION訊息,咱們看看這條訊息去哪了,直接跟進BIND_APPLICATION這個訊息的捕捉位置,
//訊息分發
class H extends Handler{
public void handleMessage(Message msg){
swich(msg.what){
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);//1
break;
...省略
}
}
}
進入訊息分發處理方法,這個方法比較長,注意閱讀能看懂的代碼,不求甚解,跟蹤data的處理,
private void handleBindApplication(AppBindData data) {
//各種初始化,比如行程名,應用名,AsyncTask執行緒池的配置,時區,網路發現
//Context的初始化
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)//1
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,//1
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
...
Application app;
app = data.info.makeApplication(data.restrictedBackupMode, null);//2
mInstrumentation.onCreate(data.instrumentationArgs);
mInstrumentation.callApplicationOnCreate(app);//3
}
通過反射實體化mInstrumentation物件,該物件為Android系統組件的管家,目前看可以控制Application和Activity的生命周期,
創建Application物件,進去看下創建的代碼
//LoadApk.java #makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation){
...
app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);//1
appContext.setOuterContext(app);
...
}
//Instrumentation.java #newApplication
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);//2
app.attach(context);//首先回呼attachBaseContext方法
return app;
}
//AppComponentFactory #instantiateApplication
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Application) cl.loadClass(className).newInstance();//3
}
可以看出最后還是通過反射初始化了Application,
最后通過mInstrumentation物件完成Application類的onCreate方法的呼叫,
mInstrumentation.callApplicationOnCreate(app);//1
//Instrumentation.java #callApplicationOnCreate
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/325627.html
標籤:其他
