Framework分析-Application的onCreate

ActivityThread并不是一个Thread,而是一个单纯的Java类,查看一下 ActivityThread 的源码final class ActivityThread ,并没有继承Thread或者实现Runnable接口,ActivityThread 其中包含 main 方法,程序的入口地方,怎么看出来的呢? 我们开发过程中总会出现程序异常信息,细心看一下log,查看最下面的几行,最终问题出在 android.app.ActivityThread.main.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:5133)
AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
AndroidRuntime: at android.app.ActivityThread.access$600(ActivityThread.java:141) 
AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99) 
AndroidRuntime: at android.os.Looper.loop(Looper.java:137) 
AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5103) 
AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method) 
AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:525) 
AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
AndroidRuntime: at dalvik.system.NativeStart.main(Native Method) 

介绍相关几个类的结构:
class ApplicationThread extends ApplicationThreadNative
abstract class ApplicationThreadNative extends Binder implements IApplicationThread
ApplicationThread (Binder)对象。其中 Binder负责接收远程AMS的 IPC调用,接收到调用
后,则通过Handler把消息发送到消息队列,UI主线程会异步地从消息队列中取出消息并执行相应操作,比如 start、stop、pause 等。

class ActivityManagerService extends ActivityManagerNative
abstract class ActivityManagerNative extends Binder implements IActivityManager

ActivityThreadmain()方法开始分析,

ActivityThread的main方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

public static void main(String[] args) {

//...

Looper.prepareMainLooper(); //主线程的Looper对象

ActivityThread thread = new ActivityThread(); // 创建ActivityThread
thread.attach(false); //

if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler(); //主线程的Handler
}

AsyncTask.init();

Looper.loop(); //消息循环

//...
}

ActivityThread的attach方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 private void attach(boolean system) {

if (!system) {
// ActivityManagerService(AMS)的代理对象,用于跟AMS通信, IActivityManager具体实现类是 ActivityManagerProxy
// ActivityManagerNative.getDefault返回ActivityManagerService的远程接口,即ActivityManagerProxy接口
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);// mAppThread是ActivityThread的成员变量, mAppThread = new ApplicationThread();
} catch (RemoteException ex) {
// Ignore
}
} else {
// ...
}
}

attach最终调用了ActivityManagerService的远程接口ActivityManagerProxyattachApplication函数,传入的参数是mAppThread(ApplicationThread类型的Binder对象),它的作用是用来进行进程间通信的.

ActivityManagerProxy的attachApplication

1
2
3
4
5
6
7
8
9
10
11
12
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder()); //将app对象加到data
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
//跟服务端通信,transact的最后一个参数的含义是执行IPC调用的模式,0 表示服务端执行完指定服务后会返回一定的数据;1 表示不返回任何数据
reply.readException();
data.recycle();
reply.recycle();
}

可以看出attachApplication方法其实就是进行远程通信,向服务端发起一个 ATTACH_APPLICATION_TRANSACTION的消息.

补充一下Android中的 Binder机制,来自《Android内核剖析》

Binder,英文的意思是别针、回形针。我们经常用别针把两张纸“别” 在一起,而在Andmid中,
Binder用于完成进程间通信(IPC),即把多个进程“别”在一起。比如,普通应用程序可以调用音乐播放服务提供的播放、暂停、停止等功能。Binder工作在Linux层面,属于一个驱动,只是这个驱动不需要硬件,或者说其操作的硬件是基于一小段内存。从线程的角度来讲,Binder驱动代码运行在内核态,客户端程序调用Binder是通过系统调用完成的.
Binder是一种架构,这种架构提供了服务端接口、Binder驱动、客户端接口三个模块。
首先来看服务端。一个Binder服务端实际上就是一个Binder类的对象,该对象一旦创建,内部就
启动一个隐藏线程。该线程接下来会接收Binder驱动发送的消息,收到消息后,会执行到Binder对象中的onTransact()函数,并按照该函数的参数执行不同的服务代码。因此,要实现一个Binder服务,就必须重载onTransact()方法。
可以想象,重载 onTransact()函数的主要内容是把onTransact()函数的参数转换为服务函数的参数,而onTransact()函数的参数来源是客户端调用transact()函数时输入的,因此,如果transact()有固定格式的输入,那么 onTransact()就会有固定格式的输出。
下面再看Binder驱动。任意一个服务端Binder对象被创建时,同时会在Binder驱动中创建一个
mRemote对象,该对象的类型也是Binder类。客户端要访问远程服务时,都是通过mRemote对象。
Binder机制

根据上面的表示,客户端调用 transact()函数之后,服务端会在 onTransact()中收到客户端传递的消息, 那么在ActivityManagerService的onTransact()方法中查找:

ActivityManagerService的onTransact

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
// ...
try {
return super.onTransact(code, data, reply, flags); //其实是调用父类ActivityManagerNative的onTransact处理
} catch (RuntimeException e) {
// The activity manager only throws security exceptions, so let's
// log all others.
if (!(e instanceof SecurityException)) {
Slog.wtf(TAG, "Activity Manager Crash", e);
}
throw e;
}
}

ActivityManagerNative的onTransact

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
// ...
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IApplicationThread app = ApplicationThreadNative.asInterface(
data.readStrongBinder()); // 取出客户端传过来的 app
if (app != null) {
attachApplication(app); //调用 ActivityManagerService的attachApplication 方法
}
reply.writeNoException();
return true;
}

ActivityManagerService的attachApplication

1
2
3
4
5
6
7
8
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid); //调用 attachApplicationLocked
Binder.restoreCallingIdentity(origId);
}
}

ActivityManagerService的attachApplicationLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// ...

thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked()); //
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();

// ...
}

最终调用客户端的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
26
27
28
29
30
31
32
33
34
35
36
 public final void bindApplication(String processName,
ApplicationInfo appInfo, List<ProviderInfo> providers,
ComponentName instrumentationName, String profileFile,
ParcelFileDescriptor profileFd, boolean autoStopProfiler,
Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {

if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}

setCoreSettings(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.initProfileFile = profileFile;
data.initProfileFd = profileFd;
data.initAutoStopProfiler = false;
sendMessage(H.BIND_APPLICATION, data); // Handler发送消息
}

回调到mH(Handler)的handleMessage方法,然后调用了 handleBindApplication(data) 方法

ApplicationThread的handleBindApplication

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
private void handleBindApplication(AppBindData data) {
// ...

// Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
// probably end up doing the same disk access.
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
Application app = data.info.makeApplication(data.restrictedBackupMode, null); //创建一个Application对象
mInitialApplication = app;

// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class
if (!data.restrictedBackupMode) {
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
// For process that contains content providers, we want to
// ensure that the JIT is enabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}

// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}

try {
mInstrumentation.callApplicationOnCreate(app);// app是Application对象
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}

先是创建Application

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
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}

Application app = null;

String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}

try {
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext); // 由instrument通过反射创建Application
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;

if (instrumentation != null) { //应为上面传过来的参数为null,所以不会执行下面的代码
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}

return app;
}

终于找到了Application的onCreate方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Perform calling of the application's {@link Application#onCreate}
* method. The default implementation simply calls through to that method.
*
* <p>Note: This method will be called immediately after {@link #onCreate(Bundle)}.
* Often instrumentation tests start their test thread in onCreate(); you
* need to be careful of races between these. (Well between it and
* everything else, but let's start here.)
*
* @param app The application being created.
*/
public void callApplicationOnCreate(Application app) {
app.onCreate();
}

概括一下就是,在ActivityThreadmain方法中,通过IPC机制和远端进行通信,服务端ActivityManagerService收到消息发送消息通知客户端,客户端的 ApplicationThread收到消息后,通过Handler发送消息,调用handleBindApplication方法,最终是通过 mInstrumentation.callApplicationOnCreate(app)回调到ApplicationonCreate方法.

文章来自: https://hanks.pub