ActivityThread源码解析
- 前言
- 类简称
- 类简介
- ActivityThread
- ActivityThread.main
- AT.attach
- AMN.getDefault()
- AMP.attachApplication
- BinderProxy.transact
- AMN.onTransact
- AMS.attachApplication
- AMS.attachApplicationLocked
前言
我们知道在Sun的Java体系中和C语言中的类或者程序入口点都是main方法,那我们的Android程序入口是不是也是某个类的main方法呢?
有一点很奇怪的是,我们平时开发中好像没接触过main方法,基本上都是与四大组件(还有一个Fragment)和Application打交道;要想弄清楚这是怎么回事,就必须要了解下当你点击手机桌面上某个APP的icon后,它是怎么从无到有运行在你的眼前的,笔者强烈建议查看以下两篇文章,你就能清楚其中逻辑
Android之APP启动流程源码深入解析
解析Android中Zygote进程是如何fork一个APP进程的
还有一点就是在接下来的分析中,会有Binder相关的知识点及AIDL的实现,可翻看如下文章
Android中进程间通信Binder机制
Android通过AIDL达到进程间通信
由上面两篇文章可以知道,当一个应用进程被创建之后,会把ActivityThread这个类加载到新的进程中来,接下来这个应用的一切操作(比如Activity的创建启动)就从ActivityThread这个类开始展开
类简称
- ActivityManagerService:AMS
- ActivityManagerNative:AMN
- ActivityManagerProxy:AMP
- ActivityThread :AT
- ApplicationThread:APT
- ApplicationThreadNative:ATN
- ApplicationThreadProxy:ATP
- ActivityStackSupervisor:ASS
类简介
这个章节的分析将会接触到大量跨进程通信,需要用到AIDL,其中涉及到的类及Activity启动相关类如下,AIDL的实现模式都是固定的
一
- IActivityManager:作为应用进程请求系统进程的接口,这时候应用进程是客户端进程,系统进程是服务端进程,客户端和服务端进程都实现且遵循这个接口规则
- ActivityManagerNative:作为服务端的“桩(Stub)”,其主要职责就是对远程(客户端进程)传递过来的数据进行”反序列化(unparcel)”
- ActivityManagerProxy:作为服务的“代理(Proxy)”,运行在客户端进程,其主要职责就是将数据进行“序列化(parcel)”,再传递给远程的“桩(Stub)”
- ActivityManagerService:IActivityManager接口中定义的业务的具体实现,运行在服务端,对“桩(Stub)”做了继承扩展
二
- IApplicationThread: 作为系统进程请求应用进程的接口,这时候应用进程是服务端进程,系统进程是客户端进程,客户端和服务端进程都实现且遵循这个接口规则
- ApplicationThreadNative:同理于ActivityManagerNative
- ApplicationThreadProxy:同理于ActivityManagerProxy
- ApplicationThread:同理于ActivityManagerService,负责响应系统进程发起的请求,帮助AMS管理相关Application中的Activity的生命周期,是ActivityThread内部类(ActivityThread是应用进程的主线程),接收到系统进程请求后通过Handler往主线程发消息,这样ApplicationThread就轻松将具体执行任务的工作转交给了主线程,用来实现AMS和AT之间的交互
三
- ProcessRecord:保存了进程运行时的信息,AMS通过ProcessRecord来维护进程运行时的状态信息,需要将应用进程绑定到ProcessRecord才能开始一个Application的构建(每个应用进程在AMS对应一个ProcessRecord)
- ActivityRecord:保存Activity运行时的信息,AMS通过ActivityRecord来维护Activity运行时的状态信息,需要将Activity绑定到AMS中的ActivityRecord才能开始Activity的生命周期(每个Activity在AMS对应一个ActivityRecord,其实就是服务器端的Activity对象的映像)
- TaskRecord:AMS抽象出来的一个Task的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序,如果了解过Activity的启动模式就知道这个用处了
- ActivityStack:AMS对Activity设计的一种堆栈机制用于管理Activity,为了让这许多Activity协同工作而不至于产生混乱,其遵循先进后出的原则,系统总是显示位于栈顶的Activity
四
- ActivityThread:APP的入口类,从main方法开始执行,就是大家口中的UI线程或者主线程,与AMS一起完成四大组件的工作
- Instrumentation:每一个应用程序只有一个Instrumentation实例,在BindApplication创建的,每个Activity内部拥有一个该对象的引用,ActivityThread对组件的操作最后都是交给它去做具体的执行
五
- ApplicationInfo:保存了应用程序的信息,包括AndroidManifest.xml中检索的信息
- Context:Activity的上下文
- ContextWrapper:继承Context,为了使用方便,对Context进行包装,而无需修改Context,内部包含一个真正的Context引用,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象,即ContextImpl对象
- Application:继承ContextWrapper,ActivityThread的上下文,用户可以继承它自定义自己的Application类,用于维护全局应用程序状态的基类
- ContextImpl:继承Context,真正实现了Context中所有函数,应用程序中调用的各种Context类的方法,其实现均来自于该类;它为Activity和其他应用程序组件提供基本上下文对象
代理和桩的理解
“代理(Proxy)”和“桩(Stub)”是Binder接口实现时成对出现的概念。可以对应到一个生活中的例子:银行的取款机就像是银行的业务代理(Proxy),客户只需要通过取款机,就能方便地完成存、取款等业务。对于客户来说,不用关心银行是什么样,钱到哪去了,只要通过代理能完成自己的业务就行了;对于取款机这个代理而言,它需要连接银行的服务器(Stub),完成数据传递,将客户的操作反馈到中心
ActivityThread
以下源码基于API24
在这个类里就能看到入口方法main
ActivityThread.main
public static void main(String[] args) {
......
//实例化了UserEnvironment,便于访问存储路径
//像平时使用的Environment.getExternalStorageDirectory出自UserEnvironment类
Environment.initForCurrentUser();
// 设置路径 确保用户能正确访问CA证书
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
//设置进程名,Process类是进程管理器
Process.setArgV0("<pre-initialized>");
//创建主线程的Looper
Looper.prepareMainLooper();
//创建ActivityThread 对象,并关联到AMS
ActivityThread thread = new ActivityThread();
thread.attach(false);
//对主线程Handler赋值
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 开启主线程循环器,不断的读取消息 派发处理消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
这个方法代码不多,但是有三处比较重要
- 创建主线程的Looper,并调用Loop方法,这样主线程就有了自己的消息队列并不停的从中取消息,然后处理;对于这个知识点可以看下笔者的Android之Handler源码分析/Looper,Message,Messagequeue三者关系
- 创建ActivityThread 对象,这个过程中会实例化几个重要的成员变量
- ApplicationThread mAppThread = new ApplicationThread()
- Looper mLooper = Looper.myLooper() 获取主线程的Looper
- H mH = new H() H继承Handler,用来处理组件的生命周期,我相信一定是google工程师词穷了,直接写个H
- 调用attach方法,这个方法很重要,看下方
AT.attach
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;//mSystemThread表明是system app 还是普通app
if (!system) { //main方法传入的是false
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
//开启JIT
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
//设置标识此应用程序/进程的对象,以报告VM错误。
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//创建ActivityManagerProxy对象
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//通过Binder跨进程调用AMS中的attachApplication
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//观察是否到heap内存上限
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 {
//当已使用内存超过虚拟机总内存的3/4,就请求释放内存
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
});
} else {
// 不要在这里设置application,如果系统崩溃,我们没办法显示警告信息
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
//添加dropbox日志到libcore
DropBox.setReporter(new DropBoxReporter());
//添加Config回调接口
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)) {
updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
mResourcesManager.getConfiguration().getLocales());
// 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) {
}
});
}
- 该方法的参数表明是否是system app调用,然后赋值mSystemThread;显然这里是普通app,进入第一个分支
- 接下来调用ensureJitEnabled()方法,目的是开启虚拟机即时编译功能,Jit全称Just-In-Time,JIT 是一种在运行时同步将字节码转化成机器码的编译器,Dalvik 直接运行转化后的机器码
- 通过ActivityManagerNative.getDefault()获取AMS的Binder代理对象,然后将APT对象发送给AMS,因为APT继承ATN,这样间接继承了IBinder接口,具备跨进程传输能力
- 通过BinderInternal类去观察虚拟机内存使用情况
- 添加dropbox日志到libcore
- 添加Config回调接口
接下来从ActivityManagerNative.getDefault()开始分析
AMN.getDefault()
/**
* 获取系统中全局的ActivityManager,这是与远程AMS通信的接口
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
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;
}
};
//将Binder对象转换成activity manager接口,并在需要时生成代理对象
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
//如果是同一个进程,那就直接返回ActivityManagerNative自己
return in;
}
//如果跨进程,那就将这个IBinder构建成代理对象返回
return new ActivityManagerProxy(obj);
}
要知道的一点是,当前应用所在进程与AMS所在的system server进程不是一个进程,如果想要与AMS通信,就必须要使用Binder机制(Binder机制的知识点可以翻看笔者以前的文章),这里跨进程通信的过程就是一个典型的AIDL实现
这里是把ActivityThread当做Client,AMS当做Server,这里是跨进程,就需要获取AMS在Client的Binder代理对象,即构建AMP返回,所以这里的IActivityManager实质上是AMP对象,接下来进入AMP
AMP.attachApplication
public void attachApplication(IApplicationThread app) throws RemoteException
{
//从Parcel池中获取Parcel对象(通讯载体),装载传递给AMS的数据
Parcel data = Parcel.obtain();
//同上,不过是装载AMS返回的数据
Parcel reply = Parcel.obtain();
//Binder唯一标志
data.writeInterfaceToken(IActivityManager.descriptor);
//asBinder()方法是返回与IApplicationThread 接口相关联的Binder对象(Binder对象实际类型是ATN)
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
因为是Binder代理对象,所以这里的mRemote是BinderProxy类型,进入看看
BinderProxy.transact
/**
*
* @param code 每个AIDL函数都有一个编号,在跨进程的时候,不会传递函数,而是传递编号告诉Server调用哪个函数
* @param data Client要发送的数据
* @param reply Server返回的数据
* @param flags
* @return
* @throws RemoteException
*/
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
return transactNative(code, data, reply, flags);
}
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException
这里最终调用到了native层,接下来经过一系列函数调用,最终调用到了**talkWithDriver()**跟驱动交互,这个函数最后通过ioctl系统调用,Client进程陷入内核态,Client调用attachApplication方法的线程挂起等待返回;驱动完成一系列的操作之后唤醒AMS所在进程,调用了AMS所在进程本地对象的onTransact函数(实际上由Server端线程池完成),这里就调用了AMN的onTransact方法(AMN即Binder本地对象)
AMN.onTransact
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
//再将binder对象转换成接口(实际类型是ATP)
IApplicationThread app = ApplicationThreadNative.asInterface(
data.readStrongBinder());
if (app != null) {
attachApplication(app);
}
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
在AMS所在进程里面,onTransact根据编号调用相关函数;在这个例子里面,由AMS的Binder本地对象(AMN)调用了Server端的attachApplication方法,从这里开始就正式进入AMS了
这边很重要的一点是:
虽然在APP进程中是将APT作为参数发送给AMS所在进程,但是因为是跨进程,经过Binder驱动处理后,AMS接收到的是APT的代理对象,即ATP,然后作为参数传给了AMS.attachApplication
AMS.attachApplication
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
//获取正在attach的应用进程id
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
这里的thread就是ATP了,AMS就用这个跟APP进程的APT通信
注意:这时候AMS所在进程作为Client,APP进程作为Server,记住一点,谁主动发起调用,谁就是Client端,你会发现这又是一个AIDL典型的实现
AMS.attachApplicationLocked
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// 通过pid查找正在attach的application record
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
if (app == null) {
//找不到对应的ProcessRecord,就杀掉pid对应的进程
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid);
//TODO: killProcessGroup(app.info.uid, pid);
} else {
try {
//退出这个应用进程的Looper
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
return false;
}
// 第一次attach,app.thread应该为null
//如果不为null,说明attach在之前的进程,那就清除它
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
// 述说整个进程
final String processName = app.processName;
try {
//注册该进程的死亡回调
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;
}
EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
//设置应用进程信息
//这一步结束,app.thread就不会为null
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
// 使用此标志来决定当用户在稍后解锁时是否需要安装provider
app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
//移出进程启动超时消息
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
//如果应用程序中存在正在启动的providers,那就延迟10s发送Contentprovider超时消息
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
try {
//获取ApplicationInfo。它保存了从AndroidManifest.xml中检索出的application标签下的信息
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
if (profileFd != null) {
profileFd = profileFd.dup();
}
//用于传递profiler设置的系统私有api
ProfilerInfo profilerInfo = profileFile == null ? null
: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
//绑定应用
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
//更新进程lru列表
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// 如果bind失败,那就重启app进程,有可能会无限循环
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
startProcessLocked(app, "bind fail", processName);
return false;
}
// 从待启动应用列表清除这个ProcessRecord
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
boolean badApp = false;
boolean didSomething = false;
// 检测最顶层的可见activity是否正在等待运行在这个进程(启动activity)
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;//didSomething表示是否有启动四大组件
}
} catch (Exception e) {
badApp = true;
}
}
// 查找所有要运行在这个进程中的sevice
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
// 检测这个进程是否有下一个Broadcast receiver
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
// 如果app因为尝试启动Broadcast receiver而死亡,就设置badApp = true
badApp = true;
}
}
//检查下一个backup代理是否在此过程中
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
notifyPackageUse(mBackupTarget.appInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
try {
thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
mBackupTarget.backupMode);
} catch (Exception e) {
badApp = true;
}
}
//如果以上组件启动出错,则需要杀死进程并移除记录
if (badApp) {
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}
//如果没有启动任何组件,那么didSomething为false
//调整进程的oom_adj值, oom_adj相当于一种优先级
//当内存出现不足时,该进程是最先被系统“杀死”
if (!didSomething) {
updateOomAdjLocked();
}
return true;
}
总结:
- 通过pid查找当前进程对应的ProcessRecord
- 如果ProcessRecord == null,说明正在attach的进程不存在,如果pid有效就杀掉pid对应的进程;反之让刚创建的activitythread退出looper循环;最后直接return
- 如果查找出来的ProcessRecord 中保存的IApplicationThread不为空,说明它是上个进程的,那就需要清除它
- 注册该进程的死亡回调,当进程死亡时会通过binder回调,来通知system_server进程死亡的消息
- 重新设置ProcessRecord信息
- 调用thread.bindApplication绑定Application到ActivityThread
- 处理activity,service,Broadcast receiver
- kill掉bad应用
我们先看第二步,退出looper循环
thread.scheduleExit()
这里的thread是入参IApplicationThread,由上面分析可知,传过来的是APT在客户端的代理ATP,那就走到ATP.scheduleExit
ATP.scheduleExit
public final void scheduleExit() throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
因为是代理对象,所以这里的mRemote是BinderProxy类型,调用后经过底层Binder调用会走到服务端的ATN.onTransact
(跟上面的AT调用AMS是一样的流程)
ATN.onTransact
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case SCHEDULE_EXIT_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
scheduleExit();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
scheduleExit()具体实现在APT
APT.scheduleExit
public final void scheduleExit() {
sendMessage(H.EXIT_APPLICATION, null);
}
继续调用到AT
AT.sendMessage
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;
}
}
}
最终会将主线程的消息队列清空并退出looper;这一系列调用就是一个AIDL的实现
再看第四步,注册APP进程的死亡通知
thread.asBinder().linkToDeath
上面说了thread是代理对象,调用的是ATP.asBinder(),通过adBinder获取到的Binder类型是BinderProxy
BinderProxy.linkToDeath
public native void linkToDeath(DeathRecipient recipient, int flags)
throws RemoteException;
这是一个native方法,经过jni调用后
android_util_Binder.linkToDeath
static const JNINativeMethod gBinderProxyMethods[] = {
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}
};
static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
jobject recipient, jint flags) // throws RemoteException
{
if (recipient == NULL) {
//jni抛异常
jniThrowNullPointerException(env, NULL);
return;
}
//获取BpBinder
BinderProxyNativeData *nd = getBPNativeData(env, obj);
IBinder* target = nd->mObject.get();
LOGDEATH("linkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) {
DeathRecipientList* list = nd->mOrgue.get();
sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
//在这里建立死亡回调
status_t err = target->linkToDeath(jdr, NULL, flags);
if (err != NO_ERROR) {
// 添加到death recipient失败, 那清除引用
jdr->clearReference();
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
}
}
}
status_t BpBinder::linkToDeath(
const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
{
Obituary ob;
ob.recipient = recipient; //该对象为JavaDeathRecipient
ob.cookie = cookie; // cookie=NULL
ob.flags = flags; // flags=0
{
AutoMutex _l(mLock);
if (!mObitsSent) { //没有执行过sendObituary,则进入该方法
if (!mObituaries) {
mObituaries = new Vector<Obituary>;
if (!mObituaries) {
return NO_MEMORY;
}
getWeakRefs()->incWeak(this);
IPCThreadState* self = IPCThreadState::self();
//向Binder驱动写命令
self->requestDeathNotification(mHandle, this);
//给驱动发消息
self->flushCommands();
}
//将新创建的Obituary添加到mObituaries
ssize_t res = mObituaries->add(ob);
return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
}
}
return DEAD_OBJECT;
}
status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
{
mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
mOut.writeInt32((int32_t)handle);
mOut.writePointer((uintptr_t)proxy);
return NO_ERROR;
}
void IPCThreadState::flushCommands()
{
if (mProcess->mDriverFD <= 0)
return;
talkWithDriver(false);
}
这里最终会调用talkWithDriver告诉Binder驱动
IPCThreadState::talkWithDriver
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
binder_write_read bwr;
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
// This is what we'll read.
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {
//将命令发送给Binder驱动
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
err = INVALID_OPERATION;
if (mProcess->mDriverFD <= 0) {
err = -EBADF;
}
} while (err == -EINTR);
......
return err;
}
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
...
binder_lock(__func__);
thread = binder_get_thread(proc); //获取binder_thread
switch (cmd) {
case BINDER_WRITE_READ: //进行binder的读写操作
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
if (ret)
goto err;
break;
case ...
}
ret = 0;
err:
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
binder_unlock(__func__);
...
return ret;
}
static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread)
{
int ret = 0;
struct binder_proc *proc = filp->private_data;
void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { //把用户空间数据ubuf拷贝到bwr
ret = -EFAULT;
goto out;
}
if (bwr.write_size > 0) { //此时写缓存有数据
ret = binder_thread_write(proc, thread,
bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
...
}
if (bwr.read_size > 0) { //此时读缓存无数据
...
}
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { //将内核数据bwr拷贝到用户空间ubuf
ret = -EFAULT;
goto out;
}
out:
return ret;
}
//处理进程发送给Binder驱动的请求
static int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed) {
uint32_t cmd;
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
void __user *ptr = buffer + *consumed;
void __user *end = buffer + size;
while (ptr < end && thread->return_error == BR_OK) {
get_user(cmd, (uint32_t __user *)ptr); //获取命令
switch (cmd) {
case BC_REQUEST_DEATH_NOTIFICATION:
//添加到当前线程的todo队列
list_add_tail(&ref->death->work.entry, &thread->todo);
break;
case ...;
}
}
}
最后一步表明只要对端进程挂掉,Binder是在底层可以从todo链表中拿出来client的信息,然后调用对应的回调方法
接下来看第六步,绑定应用
thread.bindApplication
调用原理跟上面一样,这里就不在继续阐述了,最终会调用到APT.bindApplication
APT.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) {
if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(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.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
public void setCoreSettings(Bundle coreSettings) {
sendMessage(H.SET_CORE_SETTINGS, coreSettings);
}
这里通过handler向主线程(AT)发送了两条消息SET_CORE_SETTINGS,BIND_APPLICATION
AT.H.SET_CORE_SETTINGS AT.H.BIND_APPLICATION
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case SET_CORE_SETTINGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
handleSetCoreSettings((Bundle) msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
AT.handleSetCoreSettings
private void handleSetCoreSettings(Bundle coreSettings) {
synchronized (mResourcesManager) {
mCoreSettings = coreSettings;
}
onCoreSettingsChange();
}
private void onCoreSettingsChange() {
boolean debugViewAttributes =
mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
if (debugViewAttributes != View.mDebugViewAttributes) {
View.mDebugViewAttributes = debugViewAttributes;
// 要求所有activity重启以进行更改
for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
false /* preserveWindow */);
}
}
}
AT.handleBindApplication
private void handleBindApplication(AppBindData data) {
// 将UI线程作为sensitive thread 注册到虚拟机.
VMRuntime.registerSensitiveThread();
if (data.trackAllocation) {
DdmVmInternal.enableRecentAllocations(true);
}
// 设置进程启动时间
Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
mProfiler = new Profiler();
if (data.initProfilerInfo != null) {
mProfiler.profileFile = data.initProfilerInfo.profileFile;
mProfiler.profileFd = data.initProfilerInfo.profileFd;
mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
}
// 设置进程名, 也就是说进程名是在进程真正创建以后的BIND_APPLICATION过程中才取名
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
UserHandle.myUserId());
if (data.persistent) {
// Persistent processes on 在低内存设备上无法使用硬件加速绘图,禁用以节省内存
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(false);
}
}
if (mProfiler.profileFd != null) {
mProfiler.startProfiling();
}
// 如果sdk版本在Honeycomb MR1或更早版本,需要设置Asynctask中使用的线程池
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
//如果版本大于LOLLIPOP,就不支持回收正在使用的Message
Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
/*
* 重置时区
*/
TimeZone.setDefault(null);
LocaleList.setDefault(data.config.getLocales());
synchronized (mResourcesManager) {
/*
* 更新系统配置
*/
mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
applyCompatConfiguration(mCurDefaultDisplayDpi);
}
//获取LoadedApk对象
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
//api11以后禁止在主线程使用网络
if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
StrictMode.enableDeathOnNetwork();
}
//api24及以后禁止使用file://这种格式的Uri;引入Fileprovide
if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
StrictMode.enableDeathOnFileUriExposure();
}
......
/**
* 因为前面重置了时区,所以这里需要初始化http代理.
* 这里也是AIDL的运用
*/
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try {
final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
Proxy.setHttpProxySystemProperty(proxyInfo);
} catch (RemoteException e) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw e.rethrowFromSystemServer();
}
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Instrumentation会影响类加载器,所以在设置app的context之前初始化.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
try {
ii = new ApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find instrumentation info for: " + data.instrumentationName);
}
mInstrumentationPackageName = ii.packageName;
mInstrumentationAppDir = ii.sourceDir;
mInstrumentationSplitAppDirs = ii.splitSourceDirs;
mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
mInstrumentedAppDir = data.info.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir();
} else {
ii = null;
}
//创建ContextImpl上下文
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales());
if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
final File cacheDir = appContext.getCacheDir();
if (cacheDir != null) {
// 设置临时文件缓存目录
System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
}
// 设置 generated/compiled graphics code 的缓存位置.
final Context deviceContext = appContext.createDeviceProtectedStorageContext();
final File codeCacheDir = deviceContext.getCodeCacheDir();
if (codeCacheDir != null) {
setupGraphicsSupport(data.info, codeCacheDir);
}
}
// 安装 Network Security Config Provider. 必须在应用程序代码加载前安装
NetworkSecurityConfigProvider.install(appContext);
// 继续实例化instrumentation.
if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
if (mProfiler.profileFile != null && !ii.handleProfiling
&& mProfiler.profileFd == null) {
mProfiler.handlingProfiling = true;
final File file = new File(mProfiler.profileFile);
file.getParentFile().mkdirs();
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
} else {
//第一次进来肯定是null,在这里实例化,所有activity的生命周期方法回调前都会调用该对象相关方法
mInstrumentation = new Instrumentation();
}
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
//清除内存增长上限
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
} else {
// Small heap, clamp to the current growth limit and let the heap release
// pages after the growth limit to the non growth limit capacity. b/18387825
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
}
// 应用程序和provider在设置期间允许磁盘访问,这有可能会阻塞ordered broadcasts的处理
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
try {
// 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// 不要在 restricted 模式中提供provider; 他们可能依赖于APP自定义的类
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
// 对于包含content provider的进程,我们希望在某个时刻启用JIT
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
//在mInstrumentation启动时,在加载任何应用程序代码之前调用。
//通常会被重写调用{@link #start}来开始检测线程,然后将继续在{@link #onStart}中执行。
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
//调用Application.onCreate()回调方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
这个方法很长,工作内容如下:
- 对进程基本参数的设置,比如进程名,时区,资源及兼容性设置;同时添加了对开发者的限制,如不能在主线程使用网络
- 通过getPackageInfoNoCheck获取LoadedApk对象
- 实例化ContextImpl,Instrumentation等对象
- 通过LoadedApk.makeApplication创建应用Application对象
- 调用Instrumentation.callApplicationOnCreate
AT.getPackageInfoNoCheck
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
//判断调用方和应用程序是不是同一个用户,如果不是,就不允许跨用户访问
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref;
if (differentUser) {
// 不支持跨用户访问缓存
ref = null;
} else if (includeCode) {
//进入到这个分支,根据应用包名从mPackages获取,也就是说每个app都会拥有唯一的LoadedApk对象
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref != null ? ref.get() : null;
//刚进来这个为null
if (packageInfo == null || (packageInfo.mResources != null
&& !packageInfo.mResources.getAssets().isUpToDate())) {
//创建LoadedApk对象
packageInfo = new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
if (mSystemThread && "android".equals(aInfo.packageName)) {
packageInfo.installSystemApplicationInfo(aInfo,
getSystemContext().mPackageInfo.getClassLoader());
}
if (differentUser) {
// Caching not supported across users
} else if (includeCode) {
//将新创建的LoadedApk加入到mPackages
mPackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
}
}
return packageInfo;
}
}
这里返回一个LoadedApk对象,这个对象有什么作用呢?
注意:LoadedApk对象是APK文件在内存中的表示,包含apk文件的相关信息,比如应用代码,资源文件,app里的activity和service等都可以从这获取,在使用类加载器的时候需要用到这个对象
LoadedApk.makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
//类加载器
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
//创建ContextImpl,在组件中对Context的操作都会转移到这个类
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//创建Application
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
//给mApplication赋值
mApplication = app;
......
SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
.getAssignedPackageIdentifiers();
final int N = packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
//重写所有apk库中的R常量
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
return app;
}
Instrumentation.newApplication
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
这里通过反射实例化Application ,然后调用attach
Application.attach
final void attach(Context context) {
//给ContextWrapper对象中指定真正的Context(这里的Context实际类型是ContextImpl )对象
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
ContextWrapper.attachBaseContext
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
这里对mBase 进行赋值,实际类型是ContextImpl
Instrumentation.callApplicationOnCreate
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
Application.onCreate
/**
* 在应用启动时调用 ,在创建任何activity, service,receiver,content providers之前调用
* 在此方法里操作要尽可能快(比如状态的延迟初始化),因为在这里花费太长时间将会直接影响第一个
* activity, service,receiver,content providers的性能
* 如果重写这个方法,请务必调用super.onCreate()
*/
@CallSuper
public void onCreate() {
}
这里就会回调Application的onCreate方法,我们通常会继承这个类,重写这个方法,做一些APP的初始化操作,但是切记不要做耗时复杂操作,因为这里应用才刚创建,还在初始化,可能会导致应用启动黑屏一段时间的情况
AMS.attachApplicationLocked方法执行完bindApplication后,对照着顶部目录看,接下来就是该方法第七步,启动Activity等操作了
ActivityStackSupervisor.attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
//这里维护着这台设备上所有应用的activitystack,即app的任务栈
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;
}
//取出当前任务栈中处于栈顶且运行的activity
ActivityRecord hr = stack.topRunningActivityLocked();
if (hr != null) {
//判断这个activity所在进程是否与当前调用的进程信息是否一致
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
//真正启动activity
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
throw e;
}
}
}
}
}
if (!didSomething) {
//启动失败,需要确保一个可显示的activity
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}
接下来就要真正启动activity了,看这个命名估计是google工程师也觉得逻辑有点太绕了,告诉你这真的是最后一步了,到这里也快接近尾声了
ActivityStackSupervisor.realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//如果activity正在pausing,那就跳过
if (!allPausedActivitiesComplete()) {
return false;
}
if (andResume) {
r.startFreezingScreenLocked(app, 0);
mWindowManager.setAppVisibility(r.appToken, true);
// 启动ticks以收集有关慢速APP的信息。
r.startLaunchTickingLocked();
}
// 让window manager根据新的activity顺序重新评估屏幕方向
if (checkConfig) {
Configuration config = mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false);
}
......
final ActivityStack stack = task.stack;
try {
......
//将该进程设置为前台进程PROCESS_STATE_TOP
app.forceProcessStateUpTo(mService.mTopProcessState);
//启动activity
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);
if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
// 处理heavy-weight process
if (app.processName.equals(app.info.packageName)) {
if (mService.mHeavyWeightProcess != null
&& mService.mHeavyWeightProcess != app) {
Slog.w(TAG, "Starting new heavy weight process " + app
+ " when already running "
+ mService.mHeavyWeightProcess);
}
mService.mHeavyWeightProcess = app;
Message msg = mService.mHandler.obtainMessage(
ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
msg.obj = r;
mService.mHandler.sendMessage(msg);
}
}
} catch (RemoteException e) {
if (r.launchFailed) {
// 第二次启动失败就放弃 并finish该activity
mService.appDiedLocked(app);
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
}
// 第一次启动失败就重启该进程
app.activities.remove(r);
throw e;
}
r.launchFailed = false;
//将该进程加入到mLRUActivities队列顶部
if (stack.updateLRUListLocked(r)) {
}
......
//更新所有与该Activity具有绑定关系的Service连接
if (r.app != null) {
mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
}
return true;
}
这个方法里这最重要的一步就是app.thread.scheduleLaunchActivity,这里又是一个AIDL实现,app.thread的实际类型是客户端进程在AMS端进程的代理,即ATP;接下来具体过程跟上面分析thread.scheduleExit()的时候一样,这里就不在具体阐述了,直接到ActivityThread
AT.handleLaunchActivity
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
//获取LoadedApk对象
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
}
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
//最终回调目标Activity的onConfigurationChanged()
handleConfigurationChanged(null, null);
// 在创建activity之前初始化wms
WindowManagerGlobal.initialize();
//最终回调目标Activity的onCreate
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
//最终回调目标Activity的onStart,onResume
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
} else {
// 如果失败或者其它原因就通知 activity manager 去stop activity.
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
这里调用了两个关键方法
- performLaunchActivity
- handleResumeActivity
AT.performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//获取待启动的Activity的组件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
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 = null;
try {
//通过类加载器加载activity实例
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) {
//创建该activity的context实例,实际类型是ContextImpl
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
//在这个方法里关联context,并进行Activity一些初始化操作,
//比如完成Window的创建并建立自己和Window的关联
//这样当Window接收到外部输入事件后就可以将事件传递给Activity;
//维护一个Instrumentation引用
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的onCreate
activity.mCalled = false;
if (r.isPersistable()) {
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.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
//如果之前有保存数据,这里回调OnRestoreInstance
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
}
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);
}
}
return activity;
}
AT.handleResumeActivity
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);
......
//见下方
r = performResumeActivity(token, clearHide, reason);
if (r != null) {
final Activity a = r.activity;
final int forwardBit = isForward ?
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
// 如果当前窗口没有添加到 window manager,并且它没有finished或者启动其它activity
// 那就继续添加到 window manager
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
try {
willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient && !a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
// 如果该窗口已经添加到了window manager,但是在resume期间,又启动了了一个activity
//那就设置窗口不可见
} else if (!willBeVisible) {
r.hideForNow = true;
}
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r, false /* force */);
// 如果窗口已经添加,没有finish,没有启动其它activity,那窗口可见
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
r.newConfig = null;
}
//设置输入框显示模式
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
//将当前activity视图设置可见
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
// 告诉 activity manager 该activity已经 resumed.
if (reallyResume) {
try {
ActivityManagerNative.getDefault().activityResumed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
} else {
// 当 resume 失败, 就结束这个activity
try {
ActivityManagerNative.getDefault()
.finishActivity(token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
AT.performResumeActivity
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null && !r.activity.mFinished) {
if (clearHide) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
try {
r.activity.onStateNotSaved();
r.activity.mFragments.noteStateNotSaved();
if (r.pendingIntents != null) {
//回调onNewIntent
deliverNewIntents(r, r.pendingIntents);
r.pendingIntents = null;
}
if (r.pendingResults != null) {
//回调onActivityResult
deliverResults(r, r.pendingResults);
r.pendingResults = null;
}
//在这里相继回调onStart onResume
r.activity.performResume();
......
r.paused = false;
r.stopped = false;
r.state = null;
r.persistentState = null;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to resume activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
return r;
}
到这里一个Activity就从无到有被启动且可见了
这里还涉及到一个类加载的问题没有讲到,后续再继续探索