大家都知道Java程序的入口是 main
方法,但在Android中我們只知道App啓動從Application
開始,而Android是基於Java的,本身也是從main
方法開始的,而這個 main
方法是在ActivityThread
類的。下面我們就看下ActivityThread
的main
方法是如何工作的。
1. ActivityThread
#main
public static void main(String[] args){
...
//初始化Looper
Looper.prepareMainLooper();
...
//實例化一個ActivityThread
ActivityThread thread = new ActivityThread();
//這個方法最後就是爲了發送出創建Application的消息
thread.attach(false);
...
Looper.loop();
//主線程進入無限循環狀態,等待接收消息
}
很明顯這裏使用了Handler
機制,先初始化Looper
,然後實例化一個ActivityThread
對象,而ActivityThread
類有一個H
(Handler
的子類)類型的變量mh
,並進行了實例化,而後面則是調用Looper.loop()
開啓了消息循環。
也就是說main
方法所在的線程就是我們常說的主線程,我們繼續看main
方法,可以看到創建ActivityThread
的對象後,調用了attach
方法,在這個方法裏進行了Application
、Activity
的相關創建。
2. ActivityThread
#attach
public void attach(boolean system){
...
//獲得IActivityManager實例,他是一個ActivityManagerProxy的示例
final IActivityManager mgr = ActivityManager.getService();
try {
//這裏是關鍵。mAppThread是一個ApplicationThread實例,具體的在下面說
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
首先我們拿到了一個IActivityManager
的實例,它是通過ActivityManager.getService()
獲取到的
我們看下ActivityManager.getService()
相關的源碼
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;
}
};
可以看到IActivityManager
的實例是一個ActivityManagerService
通過Binder機制得到的遠程對象,而ActivityManagerService
即AMS是運行在系統進程,主要完成管理應用進程的生命週期以及進程的Activity
,Service
,Broadcast
和Provider
等。
我們繼續回到attach
方法,這裏調用了一行代碼mgr.attachApplication(mAppThread);
,通過AMS的attachApplication
方法將mAppThread
對象關聯到了AMS。
而AMS通過調用mAppThread
的相關方法進行Application
的創建、生命週期的管理和Activity
的創建、生命週期管理等,既然bindApplication對象如此重要,那麼我們來看下它到底是什麼
3.mAppThread
是什麼?
mAppThread
是ActivityThread
的一個ApplicationThread
類型的變量,而ApplicationThread
是ActivityThread
的一個內部類,大概代碼結構如下:
public final class ActivityThread {
...
final ApplicationThread mAppThread = new ApplicationThread();
...
private class ApplicationThread extends IApplicationThread.Stub {
...
}
public static void main(String[] args){
...
}
}
顯然ApplicationThread
是一個BInder對象,可以通過Binder機制遠程訪問,這也就是爲什麼我們要將它傳遞給AMS的原因,AMS可以通過Binder機制調用它的的相關方法進行上面所說的Application
的創建、聲明週期的管理等。
首先AMS通過遠程調用ApplicationThread
的bindApplication
方法進行Application
對象的創建
4.ApplicationThread
#bindApplication
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial) {
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
...
sendMessage(H.BIND_APPLICATION, data);
}
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
可以看到bindApplication
方法通過Handler機制發送了H.BIND_APPLICATION
消息將實現交給了H
類進行處理
我們知道Handler
在handleMessage
方法裏進行消息處理
public void handleMessage(Message msg) {
switch (msg.what) {
...
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
...
}
}
消息經過Hander處理後交給了ActivityThread
的handleBindApplication
方法處理
5.ActivityThread
#handleBindApplication
private void handleBindApplication(AppBindData data) {
...
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName())
.newInstance();
//通過反射初始化一個Instrumentation儀表。
...
Application app;
try {
//通過LoadedApp的makeApplication創建Application實例
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
//讓Instrumentation儀表調用Application的onCreate()方法
mInstrumentation.callApplicationOnCreate(app);
...
}
...
}
通過上面源碼我們可以看到這裏使用data.info.makeApplication
方法創建了Application
對象
而data.info
爲LoadedApk
類型的對象,我們去這個類看它的makeApplication
方法
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
String appClass = mApplicationInfo.className;
//獲取Application的類名。明顯是要用反射了。
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread
, this);
//留意下Context
app = mActivityThread.mInstrumentation
.newApplication( cl, appClass, appContext);
//通過Instrumentation儀表創建Application
...
}
方法裏獲取了 Application
的類名,然後交給了 Instrumentation
去創建對象,我們繼續看Instrumentation
的 newApplication
方法
static public Application newApplication(Class<?> clazz
, Context context) throws InstantiationException
, IllegalAccessException
, ClassNotFoundException {
//反射創建,簡單粗暴
Application app = (Application)clazz.newInstance();
//關注下這裏,Application被創建後第一個調用的方法。
//目的是爲了綁定Context。
app.attach(context);
return app;
}
Instrumentation
直接用反射創建了Application
對象,然後調用了app.attach(context)
方法綁定Context
。這個方法裏調用了Application
的attachBaseContext
方法,這是我們應用端可以使用的最早的生命週期方法
final void attach(Context context) {
//注意這個方法是一個可以比onCreate更早被調用的方法
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInf;
}
我們繼續回到handleBindApplication
方法裏,通過LoadedApp
的makeApplication
創建Application
實例後會調用mInstrumentation.callApplicationOnCreate(app)
這行代碼執行Application
的onCreate
生命週期
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
可以看到只是簡單的調用了Application
的onCreate
方法,這是我們與Application
打交道最多的方法。
至此Application
對象已經創建出來了,並且我們已經走到了onCreate生命週期對象。Application的創建就分析到這裏了。