前言
前面我们分析了ActivityThread的main方法是如何被调用的,本篇我们来分析ActivityThread的main方法内的流程。
源码基于2.3,有错误还望指出。感谢。
代码分析
frameworks\base\core\java\android\app\ActivityThread.java#main()
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();// 1
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);//3
if (false) {
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();// 2
if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Slog.i(TAG, "Main thread of " + name + " is now exiting");
}
需要分析的为注释1,2,3处,1-2处是Handler-Looper消息循环的建立,着重看第3处。
frameworks\base\core\java\android\app\ActivityThread.java#attach()
参数boolean system,表示当前是否为系统线程。
1.这里为true时,进入到注释1处开始进行Application的创建(这里涉及到的Instrumentation本文暂不展开,等后面专门开篇讨论这个东西),并调用Application的baseAttach和onCreate方法,这里调用的地方是在ActivityThread的sysmain方法内调用的,我觉得这里就是启动Launcher的时候的流程,这不是重点,重点看注释2处,即ActivityThread的main内。
2.ActivityManagerNative.getDefault()
返回一个binder对象,这个实际上就是一个Ams实例,然后调用Ams的attachApplication方法。我们接着往下看代码。
private final void attach(boolean system) {
sThreadLocal.set(this); // 0
mSystemThread = system;
if (!system) {
......
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault(); //注释2.IActivityManager就是Binder,实际上是Ams
try {
mgr.attachApplication(mAppThread);//注释2.通过Binder与ApplicationThread关联
} catch (RemoteException ex) {
}
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process");
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
Application app = Instrumentation.newApplication(Application.class, context);//注释1
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();//Application的oncreate入口
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
ViewRoot.addConfigCallback(new ComponentCallbacks() {
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mPackages) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (applyConfigurationToResourcesLocked(newConfig)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
public void onLowMemory() {
}
});
}
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java#attachApplication()
在注释1处调用了attachApplicationLocked方法,这里的参数thread是上一步传递过来的一个ApplicationThread对象。接着往下看。
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);// 1
Binder.restoreCallingIdentity(origId);
}
}
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java#attachApplication()
这个方法忒长,略去其他代码,主要有2处比较重要:
1.注释1处,这里是调用了之前传递进来的ApplicationThread的bindApplication方法。这个主要是去绑定一些应用信息。
2.注释2处,这里就是真正的去打开一个Activity了,我们先分析注释1,再分析注释2.
接下来我们点进注释1的方法内。
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
......
// If this application record is still attached to a previous
// process, clean it up now.
......
// Tell the process all about itself.
......
if (localLOGV) Slog.v(
TAG, "New app record "<