Android的四大钻无论对开发者或是用户都意义重大,对于用户来说应用就是Activity,用户所能看到的和交互的都发生在Activity中,对于开发者来说四大组件更是开发功能个展示功能的基础和媒介,对于初级开发者每天的工作都在和四大组件打交道,它也成为初级开发者成长的重要一关,本文就从过年源码的角度分析下四大组件的启动过程;
1、Activity启动过程
Activity是我们打交道最多的组件,也是初学者接触最早的组件,特的使用范围和频率也最多,使用如此频繁的Activity你究竟了解多少呢?下面从源码的角度一起分析一下Activity的启动过程,在分析源码之前先介绍两个系统服务接口IActivityManager和IApplicationThread,它们都是在服务端只用Binder通信,(关于BinderAndroid进阶知识树——Android 多进程、Binder 你必须知道的一切)具体在本地的两个代理类如下:
- IApplicationThread
class ApplicationThread extends IApplicationThread.Stub{
…...}
- IActivityManager
class ActivityManagerService extends IActivityManager.Stub{
……}
由上面的两个代理类知道,系统中使用AIDL实现客户端和服务端的通信,介绍这两个代理类后,这里先介绍下程序在IActivityManager中如何与IApplicationThread交互的,开发者都知道Android程序的开始会执行ActivityThread.main()方法,在main()中创建了ApplicationThread实例并完成了在Ams中的设置
final ApplicationThread mAppThread = new ApplicationThread(); // 实例化ApplicaitonThread
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);//main()中调用attach()
private void attach(boolean system, long startSeq) {
final IActivityManager mgr = ActivityManager.getService();
mgr.attachApplication(mAppThread, startSeq);
}
在main()方法中调用了attach(),attach()中通过ActivityManager.getService()获取IActivityManager接口的代理类AMS,然后调用AMS.attachApplication()传入mAppThread对象;
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
}
在attachApplication中调用attachApplicationLocked()传入thread对象,attachApplicationLocked中调用了ProcessRecord.makeActive()在内部保存thread,这样AMS中就持有了ApplicationThread中代理的Binder对象;
app.makeActive(thread, mProcessStats); //
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
thread = _thread;
}
上面实现了AMS和ApplicationThread的通信,那下面开始进入Activity的启动过程分析;
- 执行启动Activity
startActivity()
Activity的启动是从一句startActivity()开始的,无论是否使用RequestCode启动,启动过程最终都会调用Activity的startActivityForResult()
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
}
}
startActivityForResult()中调用会调用Instrumentation.execStartActivity(),Instrumentation在程序的启动和Activity的启动中起着重要的作用,而且在插件化中通过Hook系统中的Instrumentation对象还可以实现更多的功能,本篇指分析和Activity启动相关的
- execStartActivity()
int result = ActivityManager.getService() //1
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent); //2、检查Activity的启动结果
- 注释1处调用IActivityManager代理类,IActivityManager是系统的服务接口,在此处采用Binder通信,ActivityManager.getService() 获取到的是它代理实现类ActivityManagerService,然后调用ActivityManagerService.startActivity()方法启动活动
- 在AMS启动活动后,调用checkStartActivityResult()检查启动结果,会根据具体的失败原因抛出异常
- ActivityManager.getService():获取IActivityManager的代理类
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
此处参照Android 8.1 源码,在系统中IActivityManager使用Singleton封装单例提供,在getService()中通过IActivityManagerSingleton.get()获取,get()会调用Singleton的create()通过ServiceManager获取对应的Binder,在根据Binder获取代理对象即ActivityManagerService对象,到此程序进入AMS中
- AMS中的startActivity()中经过一系列的调用代码最终执行到ActivityStackSupervisor的realStartActivityLocked(),realStartActivityLocked中调用IApplication接口方法处理LaunchActivity
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);
此处IApplication接口的代理类为ApplicationThread,也就是方法最终进入ApplicationThread类中,ApplicationThread为ActivityThread中的内部类,它通过Handler发送消息方式与ActivityThread通信;
@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) {
ActivityClientRecord r = new ActivityClientRecord();
.......
r.overrideConfig = overrideConfig;
sendMessage(H.LAUNCH_ACTIVITY, r);
}
ApplicationThread中创建ActivityClientRecord对象保存活动信息,然后发送Handler消息,handler消息最终被ActivityThread中的Handler子类H所消耗,在H的handleMessage()中最终调用ActivityThread中startActivityNow()方法;
- ActivityThread的startActivityNow()来启动Activity
public final Activity startActivityNow(){
ActivityClientRecord record = new ActivityClientRecord()// 1
r.token = token;
r.ident = 0;
r.intent = intent;
r.state = state;
r.parent = parent;
r.embeddedID = id;
r.activityInfo = activityInfo;
r.lastNonConfigurationInstances = lastNonConfigurationInstances;
return performLaunchActivity(r, null);//2
}
在startActivityNow()中,首先创建ActivityClientRecord保存activity启动信息,然后直接调用performLaunchActivity()启动活动,performLaunchActivity方法至关重要,Activity的一系列的初始化都在其中完成;
1.1、performLaunchActivity()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ContextImpl appContext = createBaseContextForActivity(r); //1、
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); //2、调用Instrumentation实例的方法
ContextImpl appContext = createBaseContextForActivity(r); //3、创建Activity的Context对象
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, r.configCallback);
//5
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.setState(ON_CREATE)