前言
前一篇介绍了在启动页面的时候创建进程的过程,当进程创建完成之后就会调用App的ActivityThread.main 方法。
一、mian
// ActivityThread类
public static void main(String[] args) {
... // 省略一些初始化代码
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
我们通常说ActivityThread就是应用进程的主线程,这其实是一种笼统的说法,其实ActivityThread并非真正意义上的线程,它不是Thread的子类,只不过ActivityThread充当了主线程的职能,它初始化了一个消息队列。在ActivityThread对象构建时,会创建一个Handler对象,这个Handler对象所绑定的消息队列就是主线程的消息队列。ActivityThread对象构建后,会调用自身的attach()函数,发起一个绑定操作。
private void attach(boolean system) {
// ...
// 这里传进来的为false
if (!system) {
// 设置进程名。此时,还没有ApplicationInfo,
//所以用<pre-initialized>来命名应用进程
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
// 这里得到的对象为单例的ActivityManagerService对象
// 因此我们直接转到ActivityManagerService中查看
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}else{
//
}
// ...
}
mAppThread 是ThreadMain的成员变量,类型为ApplicationThread,是一个Binder类型, 后续AMS 会通过这个Bind 对象远程调用ThreadMain 的方法。
ActivityManagerService
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
IApplicationThread thread 就是ApplicationThread的一个客户端,可以看成是我们的App.
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;
// 根据PID映射应用进程的ProcessRecord对象
//此时进程应该是创建好了
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid)
}
} else {
app = null;
}
if (app == null) {
// 获取ProcessRecord对象失败,则做一些清理操作后退出
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid)
} else {
thread.scheduleExit();
}
//返回失败
return false;
}
if (app.thread != null) {
// ProcessRecord对象之前绑定的进程还则,而当下需要将
//ProcessRecord绑定到一个新的进程
// 所以需要将之前ProcessRecord所绑定的进程信息清除
handleAppDiedLocked(app, true, true);
}
final String processName = app.processName;
try {
// 注册应用进程的DeathRecipient,当应用进程崩溃时,
//系统进程可以收到通知
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}
// 将ProcessRecord对象绑定到应用进程,
// 这样ProcessRecord就变成了“激活”状态
//这样app就可以通过thread(实际是个binder) 互相联系.
//因为我们之前只是创建了一个进程,但是这个进程没有跟
//任何程序绑定,就是一个空的架子
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
// 获取应用进程的所有Provider
//获取应用进程中所有注册的Provider,这需要通过PackageManager来扫描进程所关联的包名,所有静态的Provider信息,即ProviderInfo对象,都会保存到ProcessRecord.pubProviders变量中;
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
try {
... // 省略debug和性能相关的代码
// 发起跨进程调用,将一堆的信息传递给应用进程
// 在应用程序那里会创建对应的Application类
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null);
} catch (Exception e) {...}
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
boolean badApp = false;
boolean didSomething = false;
if (normalMode) {
try {
// 调度Activity,比如打开某个页面,此时导致进程的创建
//然后创建进程,创建之后继续打开之前想要打开的页面
//realStartActivityLocked
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}
}
if (!badApp) {
try {
// 调度Service
//同理,因为开启某个Service创建了这个进程,创建进程之后
//才真正的开始开启这个Service
//realStartServiceLocked
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
// 调度Broadcast
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
badApp = true;
}
}
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
... // 省略Backup相关的代码
}
if (badApp) {
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}
if (!didSomething) {
updateOomAdjLocked();
}
return true;
}
该函数的实现逻辑如下:
1 获取之前创建的ProcessRecord对象。通过Binder.getCallingPid()可以获取Binder接口的调用者所在进程的PID 进一步,通过PID,就能获取到应用进程对应的ProcessRecord。如果ProcessRecord对象获取失败,则表示应用进程已经被杀掉,需要清除应用进程的数据;如果ProcessRecord之前所绑定的进程信息还在,则需要清除这些信息;
2 为应用进程注册AppDeathRecipient,它是存在于系统进程的对象,当应用进程被杀掉的时候,系统进程会收到通知;
3 激活ProcessRecord对象。所谓“激活”,就是ProcessRecord已经绑定到了一个应用进程,绑定的标识就是:应用进程的ApplicationThread对象赋值给ProcessRecord.thread变量;
4 获取应用进程中所有注册的Provider,这需要通过PackageManager来扫描进程所关联的包名,所有静态的Provider信息,即ProviderInfo对象,都会保存到ProcessRecord.pubProviders变量中;
5 进行一些调试与性能相关的变量设置之后,通过IApplicationThread.bindApplication()发起跨进程调用,这样一来,诸如进程名、ApplicationInfo等信息就传递给应用进程了;
6 将信息传递给应用程序以后,就可以进行调度了,mStackSupervisor.attachApplicationLocked(app)用于调度页面,mServices.attachApplicationLocked(app, processName)用于调度服务,sendPendingBroadcastsLocked用于调度广播。实际上这三个方法一般之后调用其中的一个。
下面先看看App端的bindApplication的实现
我们平常写项目中都会给项目指定一个Application类,该类也会拥有 onCreate() 等生命周期方法,而且Application的 onCreate 方法会比第一个Activity的onCreate() 方法优先执行,接下来我们从源码的角度来分析下为什么回是这样执行的
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) {
// ...
// 这里发送了一个队列消息用于绑定Application
// 这里的队列消息由 Handler 的子类 H 类发送,进入方法内部即可查看
// H 类也是 ActivityThread 的内部类
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.initProfilerInfo = profilerInfo;
//内部会创建Applicaton对象。
sendMessage(H.BIND_APPLICATION, data);
}
handler 在收到BIND_APPLICATION消息的时候会调用handleBindApplication 方法
private void handleBindApplication(AppBindData data) {
... // 省略部分数据初始化代码
// 虽然应用进程早就已经创建,但直到这时,才知道进程名是什么
//一般就是我们的包的名字
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());
... // 省略部分进程运行信息设置代码
// 创建应用进程的Android运行环境:Context
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
if (!Process.isIsolated()) {
... // 省略与缓冲目录设置相关的代码
}
... // 省略应用进程相关的初始化代码,包含时区、StrictMode、
//调试模式等相关的设置
// 根据情况初始化Intrumentation对象
if (data.instrumentationName != null) {
...
try {
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) { ... }
mInstrumentation.init(this, instrContext, appContext,
new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
data.instrumentationUiAutomationConnection);
...
} else {
mInstrumentation = new Instrumentation();
}
...
try {
// 创建Application对象
Application app =
data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// 装载Providers
if (!data.restrictedBackupMode) {
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
...
}
}
mInstrumentation.onCreate(data.instrumentationArgs);
// 调用Application.onCreate()函数
mInstrumentation.callApplicationOnCreate(app);
}
...
}
创建完对应的Application 之后AMS 就会开始调度,这里以调度某一个页面为例子也即是
执行mStackSupervisor.attachApplicationLocked(app)方法。
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0);
}
return didSomething;
}
遍历寻找所有ActivityStack和TaskRecord,对栈顶的ActivityRecord进行操作。这里其实就是需要启动应用进程中还未启动的Activity。hr.app == null 表示ActivityRecord 还没有绑定进程,这是判断该Activity还未启动的一个重要的条件。
realStartActivityLocked从其函数取名来看,是要动真格的了,什么才叫真正启动一个Activity呢? 我们可以理解为:调度Activity.onCreate()函数执行了,就算是真正启动Activity。
// ActivityStackSupervisor 类
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app,boolean andResume, boolean checkConfig) {
// ...
//将ActivityRecord与ProcessRecord 绑定在一起
r.app = app;
app.waitingToKill = null;
r.launchCount++;
r.lastLaunchTime = SystemClock.uptimeMillis();
try {
// ...
// 这里调用了 ApplicationThread
// 中的 scheduleLaunchActivity() 方法
//ApplicationThread 是一个binder对象
app.thread.scheduleLaunchActivity(
new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
// ...
} catch (RemoteException e) {
}
return true;
}
1 将ProcessRecord和ActivityRecord关联。ActivityRecord对象的app属性,就是ProcessRecord类型;标示这个Activity 所属的进程,也标示了这个页面被启动了。
2 跨进程调用IApplicationThread.scheduleLaunchActivity(),调度启动Activity。
3 调用AS.minimalResumeActivityLocked()来显示Activity。
下面我们进入App的scheduleLaunchActivity
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
updatePendingConfiguration(curConfig);
//实际还是一个异步
sendMessage(H.LAUNCH_ACTIVITY, r);
}
handler 将会调用handleLaunchActivity 处理该消息
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
// Initialize before creating the activity
WindowManagerGlobal.initialize();
//通过一个反射创建一个Activity
//并且执行onCreate 以及onStart方法
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
//执行resume方法同时
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
if (!r.activity.mFinished && r.startsNotResumed) {
}
} else {
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
// Ignore
}
}
}
在进行了一些参数设置后,便调用ActivityThread.performLaunchActivity()函数,初始化一个Activity。如果初始化成功,便调用ActivityThread.handleResumeActivity()来处理Activity进入显示状态时需要完成的操作;如果初始化失败,则发起跨进程调用IActivityManager.finishActivity(),来通报结束一个Activity的生命周期。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
xxx
Activity activity = null;
try {
//
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//内部还是反射创建
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//最先执行attach
//这个方法很重要,相当于给创建的activity内部属性赋值.
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
/设置主题,主题是在attach之后
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
//调用onCraete
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
return activity;
}
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
unscheduleGcIdler();
mSomeActivitiesChanged = true;
// 实际执行应用进程一侧的Activity.onResume()
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
... // 省略与WindownManager相关的窗口操作
if (reallyResume) {
// 通知系统进程,Activity已经处于Resumed状态
ActivityManagerNative.getDefault().activityResumed(token);
}
}
}