首先说一下看源码的方式,首先明确看源码的目的是为了更好的指导上层开发。
看android的系统源码,重要的是理解整体的执行流程, 不要纠结于代码细节。太纠结于代码细节, 对指导上层开发并没有指导意义。
从入口main()到Applicaiton的onCreate()方法被调用
ActivityThread提供两个核心内部类 ApplicationThread和 H
public final class ActivityThread {
final ApplicationThread mAppThread = new ApplicationThread();
final H mH = new H();
private class ApplicationThread extends ApplicationThreadNative {}
private class H extends Handler {}
}
提供了main()方法作为app启动的入口
public static void main(String[] args) {
//创建Looper对象, 创建MessageQueue对象
Looper.prepareMainLooper();
//创建自己的ActivityThread对象
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
//进入消息循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
private void attach(boolean system) {
...
//获得AMS(ActivityManagerService)实例, AMS的log tag: "ActivityManager"
IActivityManager mgr = ActivityManagerNative.getDefault();
//把ApplicationThread对象传给AMS
mgr.attachApplication(mAppThread);
...
}
下面进入ActivityManagerService的attachApplication(IApplicationThread thread), ActivityThread把binder对象传给ActivityManagerService.
public final class ActivityManagerService extends ActivityManagerNative {
...
public final void attachApplication(IApplicationThread thread) {
...
attachApplicationLocked(thread, callingPid);
...
}
...
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
....
//通过binder,跨进程调用ApplicationThread的bindApplication()方法, 下面代码逻辑重回ActivityThread.java
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());
....
}
}
//ActivityThread.java
private class ApplicationThread extends Binder implements IApplicationThread{
...
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) {
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);
}
...
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把BIND_APPLICATION消息发给H处理
mH.sendMessage(msg);
}
...
}
使用H的目的是,把代码执行的逻辑从binder线程池里的线程切换到main线程里去执行.
//ActivityThread.java
private class H extends Handler {
...
public static final int BIND_APPLICATION = 110;
...
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);//调用ActivityThread的handleBindApplication()方法处理
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
}
}
//ActivityThread.java
public final class ActivityThread {
...
private void handleBindApplication(AppBindData data) {
...
//创建Instrumentation 对象
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
//创建app运行时的上下文对象,并对其进行初始化.
final ContextImpl appContext = new ContextImpl();
appContext.init(data.info, null, this);
//这里的data.info是LoadedApk类的对象
//在这里创建了上层开发者的代码中所涉及的Applicaiton类的对象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
...
//如果有ContentProvider的话, 先加载ContentProvider,后调用Application的onCreate()方法
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
}
//调Application的生命周期函数 onCreate()
mInstrumentation.callApplicationOnCreate(app);
}
...
}
// LoadedApk.java
public final class LoadedApk {
...
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
Application app = null;
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
return app;
}
...
}
// Instrumentation.java
public class Instrumentation {
...
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
...
}
实验结果:
在Application的onCreate()方法打个断点.
这里为什么会出现 access$1500()这个调用请参考我的另一篇博客:
<<从字节码看内部类是如何实现调用外部类的方法>>
最终总结, 应用启动的流程:
入口是ActivityThread.main(), 创建UI线程的消息循环, 并最终进入消息循环.
ActivityThread的内部类ApplicationThread是一个Binder,获得系统的ActivityManagerService, 调用它的attachApplication(mAppThread)并把ApplicationThread的对象mAppThread(是一个binder对象)传给ActivityManagerService, AcitivityManagerService拿到这个Binder对象后做了3件事,
attachApplication()方法内
1.
准备数据, 创建一个ProcessRecord app的对象记录一个进程的所有信息, 对各个字段进行赋值.
2.
调用mAppThread这个Binder对象的bindApplication(ProcessRecord app)方法, 把记录着进程信息的对象ProcessRecord传给ApplicationThread处理, 在bindApplication()内通过Handler mH发送一个"BIND_APPLICATION"消息让mH处理.mH处理"BIND_APPLICATION"时调用handleBindApplication(), 在里面创建Applicaiton app对象, 调用Application的onCreate(), 到这里ActivityThread的handleBindApplication()方法执行完毕.
3.
在ActivityManagerService的attachApplication()处理完第二步之后, 调用mStackSupervisor.attachApplicationLocked(app), 在里面再调用realStartActivityLocked(), 里面再调用app.thread.scheduleLaunchActivity(), 也就是mAppThread的scheduleLaunchActivity(), 在ApplicationThread的scheduleLaunchActivity()内,发送一个"LAUNCH_ACTIVITY"消息, mH处理"LAUNCH_ACTIVITY"时调用handleLaunchActivity(), handleLaunchActivity()分两步, 第一步调performLaunchActivity(),
创建Activity的对象, 依次调用它的onCreate(), onStart(). 第二步调handleResumeActivity(), 调用Activity对象的onResume().
至此, 应用启动的完整流程就分析完整了.
网友评论