[关闭]
@Awille 2018-12-02T12:30:52.000000Z 字数 9760 阅读 426

Activity启动流程

android源码分析


在日常开发过程中activity启动方法为:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);

不论是在我们应用当中进行activity的跳转,还是从系统的主界面打开我们的应用用的都是这个方法,后面这一种情景的系统主界面其实就是一个launcheractivity,我们点击我们的应用图标,就是launcherActivity跳转到我们相关的应用主activity。

入口:Activity#startActivity()

@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有几种重载的方法,最终都会调用Activity#startActivityForResult

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
        //看上面那个函数可以知道,普通的启动activity,requestCode传入值为-1
        /这表示当前不需要新的activity返回来的数据。
    if (mParent == null) {
    //mParent指的是ActivityGroup,可以在一个界面里嵌套多个Activity。
    //随着版本的升级,在API13以后就废弃掉了。
        options = transferSpringboardActivityOptions(options);
        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 {
        .....
    }
}

这里我们只关注mParent != null 的逻辑,mParent表示的是一个activityGroup,可以嵌套多个activity,但是这里activitygroup部位null到底代表了什么意思,我们先不管,留下疑问。这里我们调用了mInstrumentation.execStartActivity()方法得到activityresult对象,如果result对象不为空,我们我们又看到mMainThread.sendActivityResult(),这里的mainThread为activitythread对象。
下面关注Instrumentation#execStartActivity的方法:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManager.getService()
            .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;
}

其中ActivityManager#getService方法返回的是一个IActivityManager对象,该对象是以单例模式来实现的,首先他通过ServiceManger对象获得一个系统的binder对象,然后通过该binder对象得到他的借口实例对象,这中间涉及到AIDL来实现这些东西,IActivityManager是一个接口,根据代码推测,他的实现应该是在ActivityManagerService里面去实现的,这里我们只是获取一个实例对象,让我们可以调用其中的方法。
所以这个流程可以理解为 ActivityManger.getService是获得了一个在map中存储键值为Context.ACTIVITY_SERVICE的BINDER对象,接着在该对象当中得到IActivityManager这个接口的实例对象,接着我们用这个实例对象的startActivity的方法。
有点乱,重新整理:IActivityManger应该是一个AIDL文件,我们根据系统自动生成了IActivityManger.java文件,根据binder的知识,我们知道这个java文件当中IActivityManger类文件当中是有一个内部类Stub,该Stub类继承了Binder 并且要实现了接口的方法(这里的实现为空实现,最终的实现在别的地方),Stub的内部有一个代理类,该类实现了IActivityManger,这里同样为空实现。asinterface这个方法根据客户端与服务器是否在同一进程决定返回stub对象本身还是proxy代理对象。 具体实现该接口的类应该是继承IActivityManager方法的Stub内部类来实际上去实现IActivityManager的具体方法的。这里的ActivityManagerService一定是这么干的。我们继续往下看ActivityMangerService具体是怎么实现这个方法的。

我们先看看ActivityManagerService的声明:

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback{...}

我们果然果然没有猜错,我们下面真正开始看AMS是怎么实现的:

追踪模式启动(为了查看清晰,我把参数都省略,目前这里不是我们要查看的细节):

@Override
public final int startActivity(...) {
    return startActivityAsUser();
}

AMS#startActivityAsUser

@Override
public final int startActivityAsUser(...) {
    return startActivityAsUser(...);//这里是同一个函数两个不同的重载
}

继续往下走:

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,
        boolean validateIncomingUser) {
    enforceNotIsolatedCaller("startActivity");
    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    // TODO: Switch to user app stacks here.
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();
}

这里看到上面已经跟以前不同了,看最后的mActivityStartController.obtainStartrt().set(...).execute; 这里以前是通过mActivityStarter.startActivityMayWait直接实现的,现在加了一层管线,用controller代替先获得starter对象以后设置一系列的属性,最后调用execute方法,应该是采用了建造者模式。我们继续看:

int execute() {
    try {
        // TODO(b/64750076): Look into passing request directly to these methods to allow
        // for transactional diffs and preprocessing.
        if (mRequest.mayWait) {
            return startActivityMayWait(...);
        } else {
            return startActivity(...);
        }
    } finally {
        onExecutionComplete();
    }
}

execute方法通过参数mRequest.mayWait参数来决定不同的启动方式,这里的mayWait参数与什么有关,我猜测是启动的activity需要等待上一个结束的activity传过来的数据,我们在顶上留下疑问继续看:
ActivityStarter#startActivityMayWait:

private int startActivityMayWait {
    //code
    int res = startActivity(...);
    //code
    return res;
}

ActivityStarter#startActivity:

private int startActivity {
    final Bundle verificationBundle 
        = options != null ? options.popAppVerificationBundle() : null;
    return startActivity(ActivityRecord r, .....);
}

启动Activity的操作,交给ApplicationThread来处理:

查看ApplicationThread的声明:

private class ApplicationThread extends IApplicationThread.Stub{...}

ApplicationThread为ActivityThread的内部类,所以ActivityThread可以使用ActivityThread的方法。

ApplicationThread#bindApplication():

public final void bindApplication(...) {
    //code
    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;
    data.buildSerial = buildSerial;
    data.autofillCompatibilityEnabled = autofillCompatibilityEnabled;
    sendMessage(H.BIND_APPLICATION, data);
}

ApplicationThread#sendMessage()->H#handleMessage:
这里我们着看一个相对应的一个case:

  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, "LAUNCH_ACTIVITY");
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
            }
    }

ActivityThread#handleLaunchActivity:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;
    if (r.profilerInfo != null) {
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    }
    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null, null);
    WindowManagerGlobal.initialize();//初始化windows
    Activity a = performLaunchActivity(r, customIntent);//启动一个Activity
    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        //置为resume状态
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        if (!r.activity.mFinished && r.startsNotResumed) {
            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            ActivityManager.getService()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                        Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

ActivityThread#performLaunchActivity:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    ComponentName component = r.intent.getComponent();\\获得activity的包名,类名
    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);
    }
    ContextImpl appContext = createBaseContextForActivity(r);\\初始化context对象
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);//根据classloarder加载activity
        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);
        }
    }
    //初始化application,这里方法会执行application的oncreate方法。
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    //初始化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, r.configCallback);

}

这里可以看到activity的oncreate函数已经被调用了
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注