Activity的启动过程详解

时间:2022-05-09 15:44:18

Activity的作用

Activity是用于展示界面给用户看的。并能接收用户输入的信息来进行交互。

Activity的使用

Activity是一个很重要的一个组件,系统对Activity的内部细节做了很多封装,从而使activity的使用起来特别的简单:。

startActivity(new Intent(this,LocationManagerActivity.class));

非常的简单。系统到底是如何启动的?我们去看看源码到底是怎么启动的?由于系统启动Activity的源码内部细节过于复杂,我们只注重启动Activity的整体过程,还有思想。代码的编写每个人都有自己的风格,思想是最重要的。

启动Activity的源码分析

先看看start Activity方法

  @Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
   @Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}

可以看到startActivity有不同的重载方法,但是最终都是调用了startActivityForResult方法,去看看:

    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}

cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}

在代码的内部调用了 mInstrumentation.execStartActivity( this,mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);这里有个参数需要说明一些,mMainThread.getApplicationThread()的值其实就是Activity Thread类中内部类ApplicationThread,这是一个Binder对象。用于IPC通信用的。

进入execStartActivity()方法:

  public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
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()的startActivity()方法来启动Activity。ActivityManagerNative.getDefault()是什么?去看看代码:

static public IActivityManager getDefault(){
return gDefault.get();
}


private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>(){

protected IActivityManager create(){
IBinder b = ServiceManager.getService("activity");
...
IActivityManager am = asInterface(b);
...

}
};

从代码中看到返回的是IActivityManager类型。而ActivityManagerNative是继承于Binder并实现了IActivityManager接口,ActivityManagerService继承与ActivityManagerNative,它是IActivityManager具体的实现类。因此ActivityManagerNative.getDefault()返回的值就是ActivityManagerService。所以启动Activity的任务交到了AmS,

而在AmS服务端还会调用了一系列的方法。如图是在服务端的调用顺序,我们不深究代码的细节,反正就经过了这样的调用顺序。

Activity的启动过程详解

我们看到最后一个方法realStartActivityLocked。

 final boolean realStartActivityLocked(ActivityRecord r,                                          ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {

...

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
r.icicle, r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);

...

在代码中调用了app.thread.scheduLaunchActivity()的方法。app.thread的类型是IApplicationThread。

IApplicationThread是一个接口。
ApplicationThreadNative类继承了Binder和实现了该接口,该类是一个抽象类ApplicationThread继承了ApplicationThreadNative。

    public interface IApplicationThread extends IInterface{...}

private abstract class ApplicationThreadNative extends Binder implements IApplicationThread{...}

private class ApplicationThread extends ApplicationThreadNative {...}

因此app.thread的真正的类型是Application Thread。

经过这样的调用,Activity的启动过程就回到了Application Thread的scheduleLaunchActivity方法中,ApplicationThread类是ActivityThread的内部类。进入看看该方法的代码:


public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

updateProcessState(procState, false);

ActivityClientRecord r = new ActivityClientRecord();

r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;

r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;

r.startsNotResumed = notResumed;
r.isForward = isForward;

r.profilerInfo = profilerInfo;

updatePendingConfiguration(curConfig);

sendMessage(H.LAUNCH_ACTIVITY, r);
}

在上面的代码中,调用了 一个很重要的方法 sendMessage(H.LAUNCH_ACTIVITY, r);去看看这是什么:


private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}

private void sendMessage(int what, Object obj, int arg1) {
sendMessage(what, obj, arg1, 0, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, 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);
}

可以看到这是一个重载的方法,最终都是调用这个sendMessage(int what, Object obj, int arg1, int arg2, boolean async)方法。

在这个方法 的内部调用了 mH.sendMessage(msg);mH是一个H的对象,而H继承与Handler

    final H mH = new H();
private class H extends Handler {...}

因此sendMessage的作用其实就是发送了一条H.LAUNCH_ACTIVITY消息给H类处理。从Handler的运行机制知道,发送异步消息,最终会回调到Handler的handleMessage()的方法中,我们去看看H类中的handler Message()方法处理LAUNCH_ACTIVITY的代码:

  public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break;

...
...
...

从上面的代码可以看到,Activity的启动就交给了 handleLaunchActivity(r, null);我们去看看该方法:

      private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

Activity a = performLaunchActivity(r, customIntent);
......
if (a != null) {
......
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
......
}
.......
}

然后又交给了performLaunchActivity()方法,返回了Activity,想必在这个方法里完成了Activity对像的创建和启动。进去看看

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......

Activity activity = null;
......
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);

.....

Application app = r.packageInfo.makeApplication(false, mInstrumentation);

......

Context appContext = createBaseContextForActivity(r, activity);

......

activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);

......

if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}

......

return activity;
}

在这个方法里,做了几个重要的操作:

通过Instrumentation的newActvity的方法创建通过类加载器创建出了Activity对象。

  public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}

创建Application对象

  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 appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {...}

...
...



return app;
}

在LoadedApk类中的makeApplication方法,通过Instrumentation的newApplication方法,在方法的内部也是类加载器来创建出一个Application对象。

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;
}

创建ContextImpl和通过Activity的attach方法初始化一些重要的数据。

如果Application对象是第一次创建通过mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState)方法回调到Application的onCreate的方法。

通过 mInstrumentation.callActivityOnCreate(activity, r.state);方法回调到Activity的onCreate方法。

当回调到Activity的onCreate方法时,其实Activity的启动就已经完成了。

END