1. Application 启动流程
1 | public static void main(String[] args) { |
Android 应用启动时会执行ActivityThread的main方法,main方法中首先会创建主线程Looper,用于通过Handler机制更新UI,然后会创建ActivityThread,即UI线程。UI线程创建完毕后会调用ActivityThread的attach(boolean system)方法创建Application(thread.attach(false)),详细如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24private void attach(boolean system) {
if (!system) {
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
...
} else {
try {
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
...
}
由于调用的是thread.attach(false), 所以会执行上半部分的逻辑,首先调用ActivityManagerNative.getDefault()方法获取IActivityManager,IActivityManager继承IInterface,是一个Binder类,其实现为ActivityManagerService。下面是其实现为ActivityManagerService中attachApplication方法的实现:1
2
3
4
5
6
7
8public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
在attachApplication方法调用了attachApplicationLocked方法:1
2
3
4
5
6
7
8
9
10
11private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {
...
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
...
}
attachApplicationLocked方法则调用了thread的bindApplication方法来绑定Application。thread的类型为IApplicationThread, 而IApplicationThread也是集成的IInterface,即也是一个Binder类, 其具体实现为ApplicationThread:1
2
3
4
5
6
7
8/** {@hide} */
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{
...
}
private class ApplicationThread extends ApplicationThreadNative {
...
}
所以thread.bindApplication方法其实是调用Applicationthread中的bindApplication方法,其实现如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
...
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
从bindApplication的实现来看,其最终只是发送了一条消息,发送消息的具体实现如下:1
2
3
4
5
6
7
8
9
10
11private 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);
}
其中mH是Handle的一个子类, 从其handleMessage方法的实现可以看出绑定Application,启动Activity,启动Service等一系列功能都是有其实现的(下面的代码只是其中的一小部分):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80private class H extends Handler{
...
public void handleMessage(Message msg) {
switch (msg.what) {
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;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&2) != 0);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case PAUSE_ACTIVITY_FINISHING:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&1) != 0);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SHOW_WINDOW:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
handleWindowVisibility((IBinder)msg.obj, true);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case RESUME_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case DESTROY_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
msg.arg2, false);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
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;
case RECEIVER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
handleReceiver((ReceiverData)msg.obj);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case UNBIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
handleUnbindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
}
...
}
从handleMessage的实现来看,绑定Application是调用的handleBindApplication(data)方法:1
2
3
4
5
6private void handleBindApplication(AppBindData data) {
...
//创建Application
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
...
}
其中data.info是个LoadedApk对象,LoadedApk中makeApplication实现如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
//如果mApplication不为空就直接返回,保证只有一个Application存在
if (mApplication != null) {
return mApplication;
}
Application app = null;
java.lang.ClassLoader cl = getClassLoader();
...
//创建ApplicationContext实例,即为Application中的Context
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//创建 Application
app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
//将Application设置为ApplicationContext的外部Context
appContext.setOuterContext(app);
mActivityThread.mAllApplications.add(app);
mApplication = app;
...
return app;
}
最终在Instrumentation中通过ClassLoader加载Application字节码,再通过反射创建Application对象,其中context为上面创建的ApplicationContext,在Instrument中会被设置给Application实例对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//通过反射创建实例对象
Application app = (Application)clazz.newInstance();
//给Application设置ApplicationContext
app.attach(context);
return app;
}
到此Application就创建完了
2. Application 中的Context
通过上面的分析我们知道Application中的context是通过app.attach(context)来完成的,下面就来分析下app.attach(context)的实现:1
2
3
4
5
6
7/**
* @hide
*/
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
其实是直接调用父类中的attachBaseContext(context)方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
public Context getBaseContext() {
return mBase;
}
public AssetManager getAssets() {
return mBase.getAssets();
}
public Resources getResources()
{
return mBase.getResources();
}
...
}
在父类的attachBaseContext(Context base)中将ApplicationContext设置给mBase。Context是个纯的抽象类,ContextWrapper继承Context但并没有直接实现Context中的抽象方法, 而是通过调用mBase实现的,而这个mBase就是通过attachBaseContext(Context base)方法设置进来的ContextImpl实例对象1
2//创建ApplicationContext实例,即为Application中的Context
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
createApplicationContext方法的实现如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public Context createApplicationContext(ApplicationInfo application, int flags)
throws NameNotFoundException {
LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
flags | CONTEXT_REGISTER_PACKAGE);
if (pi != null) {
final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
new UserHandle(UserHandle.getUserId(application.uid)), restricted,
mDisplay, null, Display.INVALID_DISPLAY);
if (c.mResources != null) {
return c;
}
}
...
}
由此可见Context中定义的抽象方法最终是通过ContextImpl实现的,ContextImpl中具体方法的实现这里就不再赘述了。