ActivityThread.main
我们知道app的启动是从ActivityThread.main
方法开始的,所以我们先从main
看起
public static void main(String[] args) {
...
//创建Looper
Looper.prepareMainLooper();
//创建ActivityThread
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
//开启Looper循环
Looper.loop();
...
}
main
方法里主要做了三件事
- 创建主线程Looper,并开启循环
- 创建ActivityThread
- 调用
attach
方法
ActivityThread.attach
接下来我们看ActivityThread.attach
方法
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
...
}
...
}
...
}
attach
方法里主要做里就是调用ActivityManager.getService()
方法返回IActivityManager
类型的 Binder
对象, 具体实现是在AMS里实现attachApplication
ActivityManagerService.attachApplication
public final void attachApplication(IApplicationThread thread) {
...
attachApplicationLocked(thread, callingPid);
...
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
....
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);
...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
...
}
}
...
}
可以发现attachApplication
实际调用了attachApplicationLocked
,而在attachApplicationLocked
里又通过IApplicationThread
(其类型是ApplicationThread
是ActivityThread
的内部类,继承自IApplicationThread.Stub
) 的bindApplication
方法
ActivityThread.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) {
...
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) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
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
最终调用了mH.sendMessage
方法,因为AMS通过ApplicationThread
回调到我们的进程,这也是一次跨进程过程,而ApplicationThread
就是一个binder
,回调逻辑是在binder
线程池中完成的,所以需要通过Handler
将其切换到ui线程.所以这里调用mh.sendMessage
(mh
是ActivityThread
的内部类 H
的一个实例)来通知处理BIND_APPLICATION
事件
H.handleMessage
public void handleMessage(Message msg) {
...
switch (msg.what) {
...
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;
...
}
}
可以看到Handler.H
收到BIND_APPLICATION
事件后实际调用来handleBindApplication
方法来完成Application
的创建以及ContentProvider
的创建
ActivityThread.handleBindApplication
private void handleBindApplication(AppBindData data) {
....
final InstrumentationInfo ii;
....
if (ii != null) {
//1.创建ContentImpl
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}
//2.创建Instrumentation
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
....
//3.创建Application对象
Application app;
app = data.info.makeApplication(data.restrictedBackupMode, null);
// Propagate autofill compat state
app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);
mInitialApplication = app;
...
//4.启动当前进程中的ContentProvider和调用其onCreate方法
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.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);
}
}
//5.调用Application的onCreate方法
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
}
- 3.1
LoadedApk.makeApplication
Application的创建
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
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) {
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;
}
- 3.1.1
Instrumentation.newApplication
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}
AppComponentFactory.instantiateApplication
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Application) cl.loadClass(className).newInstance();
}
经过 上面的5个步骤就完成了Application的创建和启动,可以看到在第5步调用Application
的onCreate
方法之前,第4步进行了ContentProvicer
的创建和调用其onCreate
,这里就解释到了为什么可以在ContentProvicer.onCreate
里初始化sdk,下面介绍下ContentProvicer
的创建和调用其onCreate
- 4.1
ActivityThread.installContentProviders
private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<ContentProviderHolder> results = new ArrayList<>();
for (ProviderInfo cpi : providers) {
ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
try {
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
installContentProviders
完成了ContentProvider
的启动,它首先遍历当前进程的ProviderInfo
列表并一一调用其installProvder
方法来启动它,接着将已启动的ContentProvider
发布到AMS上,AMS会把它们存在ProviderMap
里,这样外部调用者就可以直接从AMS中获取到ContentProvider
- 4.1.1
ActivityThread.installProvider
private ContentProviderHolder installProvider(Context context,
ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
....
final java.lang.ClassLoader cl = c.getClassLoader();
LoadedApk packageInfo = peekPackageInfo(ai.packageName, true);
if (packageInfo == null) {
packageInfo = getSystemContext().mPackageInfo;
}
localProvider = packageInfo.getAppFactory()
.instantiateProvider(cl, info.name);
provider = localProvider.getIContentProvider();
if (provider == null) {
Slog.e(TAG, "Failed to instantiate class " +
info.name + " from sourceDir " +
info.applicationInfo.sourceDir);
return null;
}
localProvider.attachInfo(c, info);
....
}
这里通过类加载器完成了ContentProvider
的创建
- 4.1.1.1
ContentProvider.attachInfo
private void attachInfo(Context context, ProviderInfo info, boolean testing) {
mNoPerms = testing;
/*
* Only allow it to be set once, so after the content service gives
* this to us clients can't change it.
*/
if (mContext == null) {
mContext = context;
if (context != null) {
mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(
Context.APP_OPS_SERVICE);
}
mMyUid = Process.myUid();
if (info != null) {
setReadPermission(info.readPermission);
setWritePermission(info.writePermission);
setPathPermissions(info.pathPermissions);
mExported = info.exported;
mSingleUser = (info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0;
setAuthorities(info.authority);
}
ContentProvider.this.onCreate();
}
}
在installProvider
方法里除了完成了ContentProvider
的创建还掉用了attachInfo
,在改方法里来调用它的onCreate
方法。到此位置ContentProvider
的创建已经完成,并且它的onCreate
也被调用
网友评论