前言:
组件化开发或者第三方SDK一般都需要在Application.onCreate()中显示调用进行初始化, 记得LifecycleComponent组件当时是在ContentProvider中进行的初始化, 为何可以这样操作, 下面从进程启动的流程尝试分析一下源码, 然后再尝试分析优缺点、使用场景.
涉及到的方法
1. ActivityThread.main;
2. ActivityThread.attach(false);
3. ActivityManagerProxy.attachApplication;
4. ActivityManagerService.onTransact;
5. ActivityManagerService.attachApplication;
6. ActivityManagerService.attachApplicationLocked;
7. ApplicationThreadProxy.bindApplication;
8. ApplicationThread.onTransact(BIND_APPLICATION_TRANSACTION);
9. ApplicationThread.bindApplication;
10. ActivityThread.handleBindApplication;
1. ActivityThread.main(App进程)
public static void main(String[] args) {
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
2. ActivityThread.attach(false)(App进程)
private void attach(boolean system) {
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("", UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
// 这里的mgr指向的是ActivityManagerProxy;
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
...
}
}
3. ActivityManagerProxy.attachApplication(App进程)
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());
// IPC触发ActivityManagerService.onTransact方法;
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
4. ActivityManagerService.onTransact(system_server进程)
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder());
if (app != null) {
attachApplication(app);
}
reply.writeNoException();
return true;
}
}
5. ActivityManagerService.attachApplication(system_server进程)
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
6. ActivityManagerService.attachApplicationLocked(system_server进程)
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
// thread指向的是ApplicationThread
thread.bindApplication(...);
return true;
}
7. ApplicationThreadProxy.bindApplication(system_server进程)
@Override
public final void bindApplication(String packageName, ApplicationInfo info,
List providers, ComponentName testName, ProfilerInfo profilerInfo,
Bundle testArgs, IInstrumentationWatcher testWatcher,
IUiAutomationConnection uiAutomationConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation, boolean restrictedBackupMode,
boolean persistent, Configuration config, CompatibilityInfo compatInfo,
Map services, Bundle coreSettings) throws RemoteException {
// IPC触发ApplicationThread.onTransact
mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
}
8. ApplicationThread.onTransact(BIND_APPLICATION_TRANSACTION)(App进程)
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
switch (code) {
case BIND_APPLICATION_TRANSACTION:
{
bindApplication(...);
return true;
}
}
}
9. ApplicationThread.bindApplication(App进程)
public final void bindApplication(...) {
sendMessage(H.BIND_APPLICATION, data);
}
10. ActivityThread.handleBindApplication(App进程)
private void handleBindApplication(AppBindData data) {
try {
// 1. 触发Application.attachBaseContext();
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
// 2. 触发ContentProvider.onCreate(), ContentProvider.getContext()指向的是Application;
installContentProviders(app, data.providers);
}
}
try {
// 3. 触发Application.onCreate();
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
从上述流程知道, ContentProvider.onCreate()初始化是在Application.attachBaseContext()和Application.onCreate()之间执行;
如果自己对外提供一个组件、SDK, 如果与其他业务组件没有交互, 可以考虑在ContentProvider.onCreate()中对该组件进行初始化, 避免在Application.onCreate()中显示进行初始化.