简书 编程之乐
转载请注明原创出处,谢谢!
根据上篇文章- Launcher源码浅析,我们知道点击Launcher某个图标后,会调用Launcher的startActivitySafely方法。
如下:
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
boolean useLaunchAnimation = (v != null) &&
!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
Bundle optsBundle = useLaunchAnimation ? getActivityLaunchOptions(v) : null;
// Prepare intent
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (v != null) {
intent.setSourceBounds(getViewBounds(v));
}
try {
// ================== begin ======================
startActivity(intent, optsBundle);
return true;
} catch (ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
return false;
}
Launcher最终调用了父类 Activity 的startActivity(Intent intent, @Nullable Bundle options)方法,startActivity又调用了startActivityForResult。
在startActivityForResult方法内,会调用Instrumentation的execStartActivity方法。
注: 这里的mInstrumentation是Launcher里面的。
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
Uri referrer = onProvideReferrer();
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}
startActivityForResult里面调用了mInstrumentation.execStartActivity方法
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) { ... }
其中有个参数是mMainThread.getApplicationThread(),mMainThread是Activity类的成员变量(ActivityThread类型),mMainThread.getApplicationThread()获取的是ApplicationThread类型,ApplicationThread则是ActivityThread的内部类,可以看出ApplicationThread是一个Binder对象。
为了后面研究的方便,有必要提前说明下即将出现的这几个类的关系,它们分别是
- IApplicationThread
- ApplicationThread
- ApplicationThreadNative
- ApplicationThreadProxy
如果你查看过AIDL生成的文件,那么这几个类就比较容易理解了,IApplicationThread相当于AIDL接口
class ApplicationThread extends ApplicationThreadNative {
// 因为ApplicationThreadNative继承 Binder,且ApplicationThreadNative是抽象类,所以ApplicationThread才是真正的Binder实现。
}
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {
// Activity中常用到的那个获取接口的方法如:ServiceConnection中 IMedia iMedia = IMedia.Stub.asInterface(binder);
static public IApplicationThread asInterface(IBinder obj) {
// 内部代理类
return new ApplicationThreadProxy(obj);
}
看下这个AIDL接口的部分定义,其中后面要用到。
public interface IApplicationThread extends IInterface {
void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, boolean dontReport) throws RemoteException;
void scheduleStopActivity(IBinder token, boolean showWindow,
int configChanges) throws RemoteException;
void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
throws RemoteException;
void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) throws RemoteException;
void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, int configChanges,
boolean notResumed, Configuration config) throws RemoteException;
void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;
void scheduleDestroyActivity(IBinder token, boolean finished,
int configChanges) throws RemoteException;
void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
int resultCode, String data, Bundle extras, boolean sync,
int sendingUser, int processState) throws RemoteException;
void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments,
IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,
int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) throws RemoteException;
注意
mMainThread在Launcher中,且mMainThread变量也是在Activity.attach()中绑定的。
目前我们使用到的某些变量如(mMainThread,mInstrumentation)都是Launcher中已经初始化好的,但我们现在分析的是Launcher启动第三方Activity而不是Launcher本身,后面我们会再次遇到这些变量,这些变量的初始化和绑定过程会出现在新Activity的创建中,目前先不要对这些变量的由来疑惑!
Instrumentation 仪表盘
这个也是非常重要的一个类,大致对这个类有些了解,否则后面很难理解。
mInstrumentation是Activity的一个成员变量,且mInstrumentation是在Activity的 attach(xxx)方法里面赋值的,这个方法非常重要,里面还有mWindow = new PhoneWindow(this, window, activityConfigCallback);
等操作。后面会分析到此方法。
Instrumentation 仪表盘,命名就好像管理生命周期一样,事实也差不多如此。
看下Instrumentation 的主要方法:
execStartActivity
callApplicationOnCreate
newActivity
callActivityOnCreate
callActivityOnDestroy
callActivityOnRestoreInstanceState
callActivityOnPostCreate
callActivityOnNewIntent
callActivityOnStart
callActivityOnRestart
callActivityOnResume
callActivityOnStop
callActivityOnSaveInstanceState
callActivityOnPause
callActivityOnUserLeaving
mInstrumentation.execStartActivity内部调用了ActivityManagerNative.getDefault().startActivity()方法。
如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// ...
IApplicationThread whoThread = (IApplicationThread) contextThread;
try {
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManagerNative.getDefault()是个什么东西,这就是前面为什么要提一下ApplicationThread的原因了,形式几乎一样。
同样看下面几个类:
- IActivityManager
- ActivityManagerService(AMS)
- ActivityManagerNative
- ActivityManagerProxy
和前面完全对应,AMS闪亮登场。
很明显,AMS是真正Binder的实现类。
为了体现AMS的重要性和更好理解Binder,这里的主要部分的代码多贴一些,我们发现和ApplicationThread形式几乎一模一样,而且IActivityManager就是AIDL的接口,而ActivityManagerNative 继承自Binder 且是抽象的,真正的实现是AMS,那么AMS类在哪里呢?
ActivityManagerNative 有一个静态的getDefault方法,根据类加载机制 ,类在调用static方法时候才会初始化,此时返回gDefault.get(); Singleton是Android的一个单例封装类工具类,第一次调用get方法时候会通过create方法初始化AMS对象。
这个单例写法很有意思,又GET一个技能。
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
IBinder b = ServiceManager.getService("activity");
这个Binder对象就是ActivityManagerService。
在线 ActivityManagerService.java
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
/**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
public IBinder asBinder() {
return this;
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
}
class ActivityManagerProxy implements IActivityManager {
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public IBinder asBinder()
{
return mRemote;
}
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
// ..............
// ..............
//
}
简单看下 IActivityManager 接口的部分声明:
public interface IActivityManager extends IInterface {
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int flags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
int userId) throws RemoteException;
public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
int userId) throws RemoteException;
public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int startFlags, Configuration newConfig,
Bundle options, int userId) throws RemoteException;
public int startActivityIntentSender(IApplicationThread caller,
IntentSender intent, Intent fillInIntent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode,
int flagsMask, int flagsValues, Bundle options) throws RemoteException;
public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
Intent intent, String resolvedType, IVoiceInteractionSession session,
IVoiceInteractor interactor, int flags, ProfilerInfo profilerInfo, Bundle options,
int userId) throws RemoteException;
public boolean startNextMatchingActivity(IBinder callingActivity,
Intent intent, Bundle options) throws RemoteException;
public int startActivityFromRecents(int taskId, Bundle options)
throws RemoteException;
public boolean finishActivity(IBinder token, int code, Intent data, int finishTask)
throws RemoteException;
public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
public boolean finishActivityAffinity(IBinder token) throws RemoteException;
public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException;
public boolean releaseActivityInstance(IBinder token) throws RemoteException;
public void releaseSomeActivities(IApplicationThread app) throws RemoteException;
public boolean willActivityBeVisible(IBinder token) throws RemoteException;
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter,
String requiredPermission, int userId) throws RemoteException;
public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException;
public int broadcastIntent(IApplicationThread caller, Intent intent,
String resolvedType, IIntentReceiver resultTo, int resultCode,
String resultData, Bundle map, String[] requiredPermissions,
int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException;
public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
boolean abortBroadcast, int flags) throws RemoteException;
public void attachApplication(IApplicationThread app) throws RemoteException;
public void activityResumed(IBinder token) throws RemoteException;
我们接着上一步ActivityManagerNative.getDefault().startActivity()即
AMS(ActivityManagerService).startActivity();
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
AMS的startActivity方法调用了startActivityAsUser。
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);
}
下面是一系列的调用关系
1. AMS.startActivityAsUser-> ActivityStarter.startActivityMayWait
2. ActivityStarter.startActivityMayWait -> ActivityStarter.startActivityLocked
3. ActivityStarter.startActivityLocked -> ActivityStarter.doPendingActivityLaunchesLocked
4. ActivityStarter.doPendingActivityLaunchesLocked -> ActivityStarter.startActivityUnchecked
5. ActivityStarter.startActivityUnchecked -> mSupervisor(ActivityStackSupervisor).resumeFocusedStackTopActivityLocked();
6. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked->.targetStack(ActivityStack).resumeTopActivityUncheckedLocked
7. ActivityStack.resumeTopActivityUncheckedLocked -> ActivityStack.resumeTopActivityInnerLocked
8. ActivityStack.resumeTopActivityInnerLocked -> mStackSupervisor(ActivityStackSupervisor).startSpecificActivityLocked
9. ActivityStackSupervisor.startSpecificActivityLocked -> ActivityStackSupervisor.realStartActivityLocked
这段调用过程真是非常复杂,几乎每个类或方法都是千百行,绕的我快晕了。
这些流程,会挑选着代码讲解,如果每个流程一下子把代码贴出来,几乎都会被搞疯。
先看下最后一步:ActivityStackSupervisor.startSpecificActivityLocked
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
// mService是AMS
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
tips:
在 AMS中,每一个 Activity 组件都有一个用户 ID 和一个进程名称,其中,用户 ID 是在安装该 Activity 组件时由 PackageManagerService 分配的,而进程名称则是由该 Activity 组件的 android:process属性来决定的。
ActivityManagerService 在启动一个 Activity 组件时,首先会以它的用户 ID 和进程名称来检查系统中是否存在一个对应的应用程序进程。如果存在,就会直接通知这个应用程序进程将 Activity 组件启动起来;否则,就会先以这个用户 ID 和进程名称来创建一个应用程序进程,然后在通知这个应用程序进程将该 Activity 组件启动起来。
根据上面if语句的判断:
(1). if (app != null && app.thread != null) { }
如果app已经启动,则通过realStartActivityLocked()启动Activity。
(2). 如果app还未启动,则通过AMS创建应用进程。
上述代码第一次启动必定先运行(2)
查看ActivityManagerService类的 startProcessLocked()方法,注意startProcessLocked方法有多个重载
下面的方法调用app = newProcessRecordLocked,
最后又调用了另一个重载方法startProcessLocked。
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
if (!isolated) { // 传入的 isolated 参数为 false ,if 成立,并不是隔离的进程
// 根据进程名称和用户 ID 得到应用程序进程,由于不存在,则为 null 。
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkTime(startTime, "startProcess: after getProcessRecord");
// 省略部分代码
} else {
// If this is an isolated process, it can't re-use an existing process.
app = null;
}
// 当进程已经被分配的 PID 时,
if (app != null && app.pid > 0) {
}
// 应用程序进程不存在,创建新的进程
if (app == null) {
checkTime(startTime, "startProcess: creating new process record");
// 创建应用程序进程
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
if (app == null) {
}
app.crashHandler = crashHandler;
checkTime(startTime, "startProcess: done creating new process record");
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, "startProcess: added package to existing proc");
}
// 创建应用程序进程后,最终调用 startProcessLocked 方法
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
}
上面的startProcessLocked方法最后调用了下面这个startProcessLocked。
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
// ................ 省略
checkTime(startTime, "startProcess: starting to update cpu stats");
updateCpuStats();
checkTime(startTime, "startProcess: done updating cpu stats");
try {
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
checkTime(startTime, "startProcess: done updating pids map");
} catch (RuntimeException e) {
}
}
可以看到上面调用了Process.start方法启动一个进程。其中有这么一小段代码,如下:
if (entryPoint == null) {
entryPoint = "android.app.ActivityThread";
}
Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName,....);
Process.start()方法的第一个参数是 entryPoint 指明入口类是ActivityThread(虽然名字是XXThread,但其实是个普通类),而Java的入口一般都是main方法,那么ActivityThread 的 main 方法将在这里启动。
ActivityThread.main方法并不复杂,来看下它大致干些什么。
public final class ActivityThread {
final Looper mLooper = Looper.myLooper();
final H mH = new H();
final ApplicationThread mAppThread = new ApplicationThread();
private static volatile ActivityThread sCurrentActivityThread;
Instrumentation mInstrumentation;
static volatile Handler sMainThreadHandler;
public static void main(String[] args) {
// 初始化主线程的消息队列
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 开启消息循环
Looper.loop();
}
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) { // 是否为系统进程
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
// 省略系统进程代码
}
// 省略 ViewRootImpl 相关代码
}
}
// AMS的 attachApplication方法
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
- Looper.prepareMainLooper();准备循环主线程。
- 创建一个 ActivityThread 对象并attach();
最终sCurrentActivityThread = this; // 当前静态sCurrentActivityThread
AMS.attachApplication(mAppThread);// mAppThread是ApplicationThread - 调用Looper.loop();使主线程中消息循环
AMS.attachApplication(mAppThread);中又调用了AMS的attachApplicationLocked,查看该方法:
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
ProcessRecord app;
// 移除超时消息,应用程序在规定时间内完成了启动。
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
try{
// 序号1. ************************** IPC 调用 ActivityThread,绑定并创建Application **************************
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
}catch(Exception e){
//
}
boolean badApp = false;
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
// 序号2. ************************** 调度 Activity **************************
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}
}
// Find any services that should be running in this process...
// 序号3 ************************** 调度 Service **************************
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
// Check if a next-broadcast receiver is in this process...
// 序号4 ************************** 调度 Broadcast **************************
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
// If the app died trying to launch the receiver we declare it 'bad'
badApp = true;
}
}
}
这个地方代码很多,需要特别注意:
下面把这几个步骤分为几个序号:
- thread.bindApplication启动Application
- 启动Activity
- 启动Service
- 启动Broadcast
每个序号里面都执行跳转多次,一个序号一个序号来说,否则容易犯迷糊。
AMS.attachApplication(mAppThread) 序号一
先看 thread.bindApplication,这是一个IPC通信,thread是IApplicationThread 接口,最终调用的方法是服务端真正的Binder对象即 ApplicationThread.bindApplication()
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<String, IBinder> services, Bundle coreSettings) {
// delete the fucking code ...................
sendMessage(H.BIND_APPLICATION, data);
}
可以看到该方法发送一条H.BIND_APPLICATION消息交给handler处理。
我们看下这个Handler,在ActivityThread的内部。
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
case RELAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
} break;
case PAUSE_ACTIVITY: {
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
maybeSnapshot();
} break;
case PAUSE_ACTIVITY_FINISHING: {
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
} break;
// .................. delete
}
根据消息case BIND_APPLICATION:
将执行ActivityThread.handleBindApplication(data);方法。
private void handleBindApplication(AppBindData data) {
// 设置进程名
Process.setArgV0(data.processName);
// 创建 Android 运行环境 ContextImpl .
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
// 初始化 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 {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
// 创建 Application 对象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class
if (!data.restrictedBackupMode) {
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
// For process that contains content providers, we want to
// ensure that the JIT is enabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
}
try {
// 执行 Application 的 onCreate 方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
}
} finally {
}
}
AMS.attachApplication(mAppThread) 序号二
序号二调用了mStackSupervisor(ActivityStackSupervisor).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 (!isFocusedStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked();
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, !PRESERVE_WINDOWS);
}
return didSomething;
}
该方法遍历 ActivityStack 和 TaskRecord,找到位于 Activity 堆栈顶端的一个 ActivityRecord 对象 hr,接着检查这个 Activity 组件的用户 ID 和 进程名是否与 ProcessRecord 对象 app 所描述的应用程序的用户 ID 和进程名一致,如果一致,则调用 StackSupervisor.realStartActivityLocked方法来请求该应用程序进程启动一个 Activity 组件。
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// .... 删 删 删 删 删 删 删 删 fuck
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
}
StackSupervisor.realStartActivityLocked方法内部调用了app.thread.scheduleLaunchActivity()方法,其中thread是ApplicationThread类型,binder对象。
ApplicationThread.scheduleLaunchActivity方法如下:
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
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();
// .......... delete code
sendMessage(H.LAUNCH_ACTIVITY, r);
}
scheduleLaunchActivity里面同样是发送了一条handler消息。
根据上面handleMessage处理的消息类型,将执行
ActivityThread.handleLaunchActivity()方法。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// Initialize before creating the activity
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
} else {
// If there was an error, for any reason, tell the activity
// manager to stop us.
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
// Ignore
}
}
}
分别调用:
- performLaunchActivity将 Activity 组件启动起来
- handleResumeActivity方法将 Activity 组件的状态设置为 Resumed。
下面只讲Activity a = performLaunchActivity(r, customIntent);
就可以了,handleResumeActivity设置Resumed就没有什么必要说了。
ActivityThread.performLaunchActivity是个重重重要的方法 ,我们最前面提到某些 重要角色对象 的设置都是在这个方法里面初始化的。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 获取ActivityInfo信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
// 获取要启动的Activity的组件信息
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
// 根据相关信息构建组件对象
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
// 通过反射 新建一个 Activity 对象
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 {
// 这个地方我稍有疑惑,因为根据前面的逻辑 BIND_APPLICATION消息[app == null情况下]->handleApplication()中
// 已经使用LoadedApk.makeApplication()生成一个Application对象了,这里在case LAUNCHER_ACTIVITY又调用一遍。
// 不过LoadedApk.makeApplication有判断null处理,所以只会返回一个Application对象啦!
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// 创建 Activity的 ContextImpl ,作为 Activity 的运行上下文环境
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
// 构造Configuration对象
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
// ============= Window对象
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// ******** 重要 : activity.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, window);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
// 设置主题
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
// 根据是否需要持久化调用此方法通知Activity已被创建和启动
// 回调 Activity 的 onCreate 函数
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
// 回调 Activity 的 onStart 函数
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
// Activity 的 onRestoreInstanceState 函数
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
// 返回创建并初始化过的activity对象
return activity;
}
终于讲完了序号1和序号2,这里的序号1和序号2指的是下图这几个步骤的前2个:
讲了这么多,AMS.attachApplication这个方法还没执行完,我了个去,累死了!写的最累的一篇博客了。
时序图实在懒得画了,画这个图估计也够呛,这篇文章篇幅虽然和其他分析AMS的文章比起来算是短些了,因为很多文章几乎把源码全部都贴上了,我看着都晕,单单
AMS.startActivityAsUser->ActivityStackSupervisor.realStartActivityLocked
那9步就够你贴上十几页了,那一部分确实跳来跳去搞得人眼花缭乱,而且每段代码都是千百行,但是最重要的确是最后那两步,所以我把该省略的跳转代码都省掉了,如果具体研究某个步骤就比较容易了,有兴趣的可以查找9步中的某一段代码进行具体分析。花了整整3天时间,如果你喜欢,请点一个赞!nnd......Fuck the code!!!
小结
从上面的执行流程:我们发现Application会创建一个appContext,一个Activity会创建一个Context,(一个Service也会创建一个Context),那么一个应用中 Context的总数 = Activity对象数 + Service对象数 + 1个Application对象
。四大组件中的BroadcastReciver和ContentProvider的Context都是直接或间接来自于 Application,Activity,Service。
最后找来自己参考过的一种博主画的图,和我的流程差不多,盗图一张!
相关补充说明
ActivityStack :Android 中的 Activity 组件堆栈信息,也就是 Task。
ActivityStackSupervisor:管理ActivityStack的类。
参考
Android开发艺术探索
Android源码设计模式
Android 7.0 源码
Activity启动过程分析(从Launcher启动)
Android 6.0 Launcher 启动 Activity 过程源码分析(二)