首先说一下看源码的方式,首先明确看源码的目的是为了更好的指导上层开发。
看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 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 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 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().
至此, 应用启动的完整流程就分析完整了.