ActivityThread
翻譯:它管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行,根據(jù)活動(dòng)管理器的請(qǐng)求虫埂,在其上調(diào)度和執(zhí)行活動(dòng)祥山、廣播和其他操作。
ActivityThread是app啟動(dòng)的入口告丢,會(huì)執(zhí)行main方法:
public static void main(String[] args) {
//創(chuàng)建MainLooper
Looper.prepareMainLooper();
//創(chuàng)建ActivityThread枪蘑,執(zhí)行attach()方法,第一個(gè)參數(shù)代表是否是系統(tǒng)應(yīng)用损谦。
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
//sMainThreadHandler就是ActivityThread用于處理消息的handle
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//執(zhí)行 Looper.loop()
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
創(chuàng)建MainLooper岖免,并儲(chǔ)存到從sThreadLocal中。
Looper-》
//->Looper.prepareMainLooper
public static void prepareMainLooper() {
//創(chuàng)建looper照捡,并儲(chǔ)存
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
//獲取looper
sMainLooper = myLooper();
}
}
//->Looper.prepare
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
//->Looper.myLooper
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
看下ActivityThread的成員變量:
public final class ActivityThread {
//ApplicationThread是ActivityThread的內(nèi)部類颅湘,其實(shí)現(xiàn)IApplicationThread.Stub的接口
//Binder通信的時(shí)候,他的代理對(duì)象在服務(wù)端栗精,用來(lái)和系統(tǒng)服務(wù)交互闯参,并將服務(wù)端的消息發(fā)送到客戶端,也就是ActivityThread悲立。
final ApplicationThread mAppThread = new ApplicationThread();
//從sThreadLocal.get()到剛才創(chuàng)建的mainLopper對(duì)象
final Looper mLooper = Looper.myLooper();
//用于發(fā)送和處理消息的handle 鹿寨,繼承Handle
final H mH = new H();
}
繼續(xù)看下attach方法:
//上面調(diào)用處傳進(jìn)來(lái)了第一個(gè)參數(shù)是false,表示是否是系統(tǒng)應(yīng)用,第二個(gè)參數(shù)是時(shí)間薪夕。
private void attach(boolean system, long startSeq) {
if (!system) {//不是系統(tǒng)應(yīng)用
//這里創(chuàng)建的mgr就是服務(wù)端ams在客戶端的代理類脚草,主要用于binder通信。
final IActivityManager mgr = ActivityManager.getService();
//這里會(huì)創(chuàng)建application原献,并且會(huì)將客戶端的ApplicationThread的對(duì)象傳遞給服務(wù)段馏慨,進(jìn)行一個(gè)綁定,用來(lái)binder通信
mgr.attachApplication(mAppThread, startSeq);
} else {//是系統(tǒng)應(yīng)用
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
}
}
也就是說(shuō)姑隅,向ams發(fā)送創(chuàng)建Applicaiton的請(qǐng)求和ams綁定客戶端ApplicationThread對(duì)象的操做都在這里面写隶。
繼續(xù)跟進(jìn)看下ActivityManagerService-》attachApplication
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
ActivityManagerService-》attachApplicationLocked
private boolean attachApplicationLocked(IApplicationThread thread, int pid) {
if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
}
return true;
}
很明顯,通過(guò) IApplicationThread 又將代碼回調(diào)到了 Client 端讲仰。
看ApplicationThread-》bindApplication方法:開(kāi)始發(fā)送H.BIND_APPLICATION的消息了慕趴。當(dāng)然接受的地方就是在ActivityThread里面了。
public final void bindApplication(... ...) {
sendMessage(H.BIND_APPLICATION, data);
}
// 根據(jù)消息機(jī)制,我們?cè)?ActivityThread#H 中尋找消息處理
public void handleMessage(Message msg) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
我們先了解下這個(gè)服務(wù)端給我們的AppBindData是個(gè)什么:
首先他也是ActivityThread的內(nèi)部類秩贰,看下的成員都有啥霹俺。
static final class AppBindData {
LoadedApk info;//關(guān)于當(dāng)前加載的 .apk 的本地狀態(tài)。
String processName;//進(jìn)程名稱
ApplicationInfo appInfo; //檢索有關(guān)特定應(yīng)用程序的信息毒费。這對(duì)應(yīng)于從 AndroidManifest.xml 的<application>標(biāo)記收集的信息丙唧。
ComponentName instrumentationName;//instrumentation名字,通過(guò)源碼我猜是ams通過(guò)我們的應(yīng)用信息生成的觅玻,然后讓我們按照這個(gè)名稱去創(chuàng)建隊(duì)員的instrumentation想际。因?yàn)榉瓷渖蒊nstrumentation就是按照的這個(gè)名字。
}
繼續(xù)看下拿這個(gè)AppBindData去干啥了:
ActivityThread-》handleBindApplication
/
private void handleBindApplication(AppBindData data) {
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
ii = new ApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName, 0);
} else {
ii = null;
}
// 根據(jù)上層調(diào)用傳入的參數(shù)溪厘,決定初始化 mInstrumentation 實(shí)例的方式
// 1. 使用 ClassLoader 初始化胡本;
if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(......);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
//利用這個(gè)AppBindData的instrumentationName去創(chuàng)建Instrumentation
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
}
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(... ...);
} else {
//2. InstrumentationInfo==null,直接 new 對(duì)象
mInstrumentation = new Instrumentation();
}
try {
// 調(diào)用 makeApplication 去創(chuàng)建 Application 對(duì)象,info就是LoadedApk畸悬。
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// 初始化 application 對(duì)象后侧甫,通過(guò) mInstrumentation 調(diào)用 application 的 onCreate 方法
mInstrumentation.callApplicationOnCreate(app);
}
}
創(chuàng)建Application 對(duì)象:
LoadedApk-》makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 入?yún)⒌?instrumentation 為 null,使用 ActivityThread 的 mInstrumentation
app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
appContext.setOuterContext(app);
return app;
}
實(shí)際還是在Instrumentation中創(chuàng)建Application蹋宦。
Instrumentation-》newApplication
public Application newApplication(ClassLoader cl, String className, Context context) {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context){
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
接下來(lái)再看一下Activity啟動(dòng)的時(shí)候披粟,ActivityThread做了什么?
當(dāng)我們調(diào)用startActivity的時(shí)候冷冗,最后通過(guò)Instrumentation.execStartActivity()方法守屉,里面會(huì)去獲取ams在客戶端的代理類,跟AMS進(jìn)行Binder通信蒿辙,ams會(huì)去調(diào)用自己的startActivity()方法拇泛,ams處理完成后,通過(guò)在服務(wù)端的ApplicationThread的代理類將啟動(dòng)事件傳遞到ApplicationThread中思灌,ApplicationThread通過(guò)發(fā)送handler消息到ActivityThread俺叭,然后ActivityThread收到消息后處理啟動(dòng)Activity的邏輯。
也就是說(shuō)針對(duì)Activity的相關(guān)的操作泰偿,最后都要到這里去執(zhí)行熄守。
查看==ActivityThread.performLaunchActivity()==:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
//創(chuàng)建Activity,還是mInstrumentation創(chuàng)建的甜奄。還是發(fā)射柠横。
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
}
//執(zhí)行activity的attach方法
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
//這個(gè)方法會(huì)去執(zhí)行 activity.performCreate(icicle);接著就是activiy的onCreate方法了,參數(shù)是Bundle课兄。
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
}
Activity創(chuàng)建后取執(zhí)行attach方法了牍氛,之后執(zhí)行oncreate方法。我們看下attach方法:
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
mWindow = new PhoneWindow(this, window, activityConfigCallback); mWindow.getLayoutInflater().setPrivateFactory(this);
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mAssistToken = assistToken;
mIdent = ident;
mApplication = application;
mIntent = intent;
mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mWindow.setWindowManager(
(WindowManager) context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
}
可以看到烟阐,fragment也進(jìn)行attach操作了搬俊,phoneWindow也是這時(shí)候創(chuàng)建的紊扬,window的LayoutInflater也是這時(shí)候創(chuàng)建的,然后將一些參數(shù)進(jìn)行了應(yīng)用賦值唉擂。最后給windon設(shè)置了setWindowManager餐屎。
最后總結(jié)一下,ActivityThread它管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行玩祟,根據(jù)活動(dòng)管理器的請(qǐng)求腹缩,在其上調(diào)度和執(zhí)行活動(dòng)、廣播和其他操作空扎〔厝担~~~~~
最后,睡覺(jué)啪啪啪~~~