Activity具體是怎麽創建的?又是怎麽顯示出來的?
帶著這些問題往下看!!!
先來一張大概的程序調用流程圖
startActivity
通常啟動一個activity都是通過以下的方式:
startActivity(new Intent(this, MainActivity.class));
跟蹤源碼到 Android.app.Activity.Java
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
不管是調用startActivity() 還是 startActivityForResult(),最終都會調用下面的函數!
Activity#startActivityForResult
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
在這個方法體內,調用了 Instrumentation 的 execStartActivity() 函數!接收返回的 Instrumentation.ActivityResult 對象!
當返回對象不為空時,調用 ActivityThread 的 sendActivityResult() 用來返回結果!
Instrumentation#execStartActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// ...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
只看關鍵代碼。這裏又出現一個類 ActivityManagerNative 。
ActivityManagerNative#getDefault().startActivity
static public IActivityManager getDefault() {
return gDefault.get();
}private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
Singletion 是系統內部提供的單例的封裝類!
第一次調用get()方法時,會回調create() 創建對象,後序調用則直接返回第一次創建的對象!
從這個方法體可以明顯的觀察出,這是一個 AIDL 操作!
首先從ServiceManager中拿到Binder對象!
然後在 asInterface() 中進行判斷,如果調用者與服務端不在同一進程,則返回代理對象!
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);
}
asInterface() 就是用於將服務端的Binder對象轉換成客戶端所需的AIDL接口類型的對象。如果客戶端和服務端處於同一進程,則返回服務端的IActivityManager對象,否則返回代理對象。
代理對象就是ActivityManagerProxy 。
看到這裏,會發現這是一個典型的AIDL模式!
只不過這裏沒有xxx.aidl 文件!
IActivityManager.java 就相當於編譯aidl之後生成的類文件,繼承 IInterface.java 這個接口!
普通aidl文件編譯生成的 Ixxx.java文件中,包含兩個內部類,一個是Stub,一個是Proxy!但是在這裏分為兩個文件!
ActivityManagerNative.java 就相當於Stub,同樣是繼承Binder類,實現了IActivityManager 。通Stub類一樣,裏面包含 asInterface(), asBinder(), onTransact() 等函數!
ActivityManagerProxy.java 相當於Proxy(從名稱很明顯就看的出來)。它是ActivityManagerNative 的內部類!
ActivityManagerService.java 是 ActivityManagerNative.java 的具體實現。也就是說AMS才是服務端的具體實現!
因字數限制,完整內容請點擊左下角原文鏈接查看~~
閱讀原文
大連男科檢查醫院 http://www.39552222.com/
大連婦科 http://www.dlfkyy.net/
Activity具體是怎麽創建的?又是怎麽顯示出來的?