当我们第一次启动一个应用程序组件时,如果该应用没有任何组件存在,那么系统首先会创建该应用程序的ActivityThread
ActivityThread的创建过程是很复杂的,当程序进程第一次启动时,系统会在主线程中调用ActivityThread的main()方法,从而完成ActivityThread的创建。
ActivityThread是什么?网上有很多说法:ActivityThread是应用程序的主线程,其实这种说法不准确。先来看看ActivityThread的官方说明:
/**
* This manages the execution of the main thread in an
* application process, scheduling and executing activities,
* broadcasts, and other operations on it as the activity
* manager requests.
*
* {@hide}
*/
public final class ActivityThread {
可以看到ActivityThread本身并不是一个线程。它负责管理主线程在进程中的执行,调度和执行Activity、BroadCast以及其他ActivityManagerService(以下简称AMS)请求的操作。具体来说,就是ActivityThread接收AMS的请求,负责应用程序的管理,主要是回调应用程序的生命周期函数。准确的说法是ActivityThread是一个运行在主线程的类,负责完成主线程的逻辑。
系统在创建进程并初始化主线程的时候,会调用ActivityThread的main()方法,代码如下:
/**
*当启动一个组件时,如果该组件的应用程序进程没有创建,则创建该组件的进程,并为该进程创建
*主线程,同时调用该方法
*/
public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
//为主线程创建Looper
Looper.prepareMainLooper();
//创建ActivityThread
ActivityThread thread = new ActivityThread();
//将ApplicationThread传递给AMS,通知AMS ActivityThread已经创建完毕
thread.attach(false);
//初始化主线程的Handler,以后我们可以看到,对应用组件的的生命周期的回调是
//通过Handler发消息完成的
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//加载AsycTask,并且创建其内部的Handler。
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
//开启主线程的消息循环。
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
可以看到main方法是该类的一个静态方法,主要完成以下操作:
- 为主线程创建Looper
- 创建ActivityThread
- 将ApplicationThread传递给AMS,通知AMS ActivityThread已经创建完毕
- 初始化主线程的Handler
- 加载AsycTask,并且创建其内部的Handler。
- 开启主线程的消息循环。
下面我们具体分析。
先看看 Looper.prepareMainLooper();
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
不难发现,它在主线程中创建了一个Looper对象。
紧接着,ActivityThread thread = new ActivityThread();创建了ActivityThread,并且会导致 mH和ApplicationThread的初始化。
然后,看看thread.attach(false):
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//将ApplicationThread传递给AMS
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
} 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",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//创建Application对象
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
//调用Application的onCreate()方法
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
//添加配置Callback
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
//
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
可以看出 attach()主要完成以下几个步骤:
- 建立ApplicationThread和AMS之间的联系
- 创建Application对象并调用onCreat()方法,可以看到,Application对象,每个进程都会有且仅初始化一次。
- 添加ConfigurationCallback。
再看看AyncTask.init():
/** @hide Used to force static handler to be created. */
public static void init() {
sHandler.getLooper();
}
这个方法时一个静态方法,作用是强制创建AsyncTask内部的Handler。由于异步任务是在线程池中执行任务,所以,必须使用Handler实现子线程和主线程之间的通讯。
最后 Looper.loop()方法为主线程开启消息循环。
至此,ActivityThread创建完毕,接下来,AMS就可以通过ApplicationThead来控制组件的生命周期。