Activity启动流程

本文主要是对activity的启动流程做一个简单分析

1、Activity.java
位于/frameworks/base/core/java/android/app/目录。有activity发起startActivity()请求,再调用到startActivityForResult()。

    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
        if (mParent == null) {
            // Instrumentation是什么?mMainThread(ActivityThread)又是什么?
            // ApplicationThread又是什么?
            Instrumentation.ActivityResult ar = 
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                // ActivityThread.sendActivityResult()又做了什么?
                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;
            }
        } 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);
            }
        }
    }  

ActivityThread.getApplicationThread()获取到的对象实际上是ActivityThread的一个内部类对象ApplicationThread,而ApplicationThread的父类ApplicationThreadNative又是什么呢?我们接着向下看。

2、Instrumentation.java
位于/frameworks/base/core/java/android/app/目录。其类的介绍如下:

/**
 * Base class for implementing application instrumentation code.  When running
 * with instrumentation turned on, this class will be instantiated for you
 * before any of the application code, allowing you to monitor all of the
 * interaction the system has with the application.  An Instrumentation
 * implementation is described to the system through an AndroidManifest.xml's
 * <instrumentation> tag.
 */
public class Instrumentation {

大体的意思就是说:这个类是应用测试框架的基本实现。如果测试框架打开,该类会最先初始化,并允许你监控到系统和应用的所有交互。如果你要使用自定义的测试框架,就必须在AndroidManifest.xml中使用instrumentation标签注明你的实现类。

注意:Instrumentation在我们写安卓的测试代码中是必须要用到的。我们在AndroidManifest.xml中声明的测试框架,实际就是继承与这个Instrumentation。activity的很多对外操作,都将通过该类传递出去,外部信息也将通过该类传递到activity。猜想:如果需要实现一些特殊的功能,比如说权限监控,应该可以通过重写该类实现。

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        // 实际上是ActivityThread的一个内部类对象ApplicationThread
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    // 在同一进程内寻找匹配的activity
                    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.setAllowFds(false);
            intent.migrateExtraStreamToClipData();

            // 在不同进程内寻找匹配的activity,借助ActivityManagerNative实现跨进程通讯
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, null, options);

            // 检查返回值,必要时抛出ActivityNotFoundException异常
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }

ApplicationThread继承与ApplicationThreadNative,而ApplicationThreadNative则实现了IApplicationThread的接口。好吧,这个是不是和native binder相关类中介绍的native binder的继承层次类似?确实是这样的!IApplicationThread定义了一系列的binder接口,而ApplicationThreadNative是IApplicationThread的Bn端框架实现,ApplicationThreadNative中定义的另一个ApplicationThreadProxy类,则是IApplicationThread的Bp端框架实现。

ActivityMonitor是Instrumentation的内部类,主要是记录了Instrumentation启动的activity信息,包括IntentFilter、class、result等信息。

Instrumentation.execStartActivity()方法,现在其内部的ActivityMonitor队列中查找匹配的activity。如果没有找到,则进入到ActivityManagerNative.startActivity()中,并调用checkStartActivityResult()检查返回结果,判断是否出了异常。

IApplicationThread的接口定义如下。大家有没有觉得这些接口和activity的生命周期类似?实际上,这些接口是ActivityManagerService用来直接控制Activity的。

public interface IApplicationThread extends IInterface {
    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges) 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, boolean isForward) 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,
            Bundle state, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
            String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
            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;
// 。。。。省略

4、ActivityManagerNative.java
位于/frameworks/base/core/java/android/app/目录下,与其对应的是IActivityManager.java接口定义。它们之间的关系和前边介绍的ApplicationThreadNative.java、IApplicationThread.java的关系一样,就不再分析。IActivityManager定义了接口;ActivityManagerNative继承与Binder,实现了IActivityManager接口,是IActivityManager的Bn端实现;而ActivityManagerNative的内部类ActivityManagerProxy则是IActivityManager接口的Bp端实现。以下是它的一些binder接口:

public interface IActivityManager extends IInterface {
    public int startActivity(IApplicationThread caller,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
            int requestCode, int flags, String profileFile,
            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException;
    public int startActivityAsUser(IApplicationThread caller,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
            int requestCode, int flags, String profileFile,
            ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
    public WaitResult startActivityAndWait(IApplicationThread caller,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
            int requestCode, int flags, String profileFile,
            ParcelFileDescriptor profileFd, Bundle options, int userId) 
// 。。。。省略

怎么样?这些接口和我们在Context中定义的一些接口是不是很像?

看看ActivityManagerNative的几个关键方法:

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

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            // 从ServiceManager处获取activity manager的binder对象
            IBinder b = ServiceManager.getService("activity");

            // 将binder对象转换为接口对象
            IActivityManager am = asInterface(b);
            return am;
        }
    };

5、ActivityManagerService.java
位于/frameworks/base/services/java/com/android/server/am目录。继承与ActivityManagerNative,也就是说它是IActivityManager的Bn端实现。它管理系统内所有的activity(通过ActivityStack管理)、service、provider和receiver。应用层调用的startActivity()方法最终会到达ActivityManagerService中。

    public final int startActivity(IApplicationThread caller,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags,
            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
    }

    public final int startActivityAsUser(IApplicationThread caller,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags,
            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, true, "startActivity", null);
        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                null, null, options, userId);
    }

可以看到startActivity()传递到了mMainStack(ActivityStack对象)。

6、ActivityStack.java
位于/frameworks/base/services/java/com/android/server/am目录。ActivityStack主要是用来存储和管理所有的Activity的。Activity在ActivityStack中的表现形式是ActivityRecord。ActivityStack管理所有activity的堆栈结构,BnActivityManagerService的命令都会传到ActivityStack中,最终传递到相应的activity进程中。而相应的activity执行命令,状态发生变化,并将状态上报到ActivityManagerService,并最终保存在ActivityStack中的某一个ActivityRecorder。

    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, String profileFile,
            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
            Bundle options, int userId) {
        // 。。。。省略,检查intent的合法性

        // Collect information about the target of the Intent.
        // 解析activity信息,包名、类名、theme、label、lunch mode等等
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
                profileFile, profileFd, userId);

        synchronized (mService) {
            if (mMainStack && aInfo != null &&
                    (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
                // This may be a heavy-weight process!  Check to see if we already
                // have another, different heavy-weight process running.
                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                    if (mService.mHeavyWeightProcess != null &&
                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {

                        // 。。。。省略,如果同一包名的进程已经启动,则获取ProcessRecord信息,并使用ProcessRecord中的uid和pid信息,修正caller uid和pid信息。                        
                    }
                }
            }

            // 启动activity
            int res = startActivityLocked(caller, intent, resolvedType,
                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
                    startFlags, options, componentSpecified, null);

            if (mConfigWillChange && mMainStack) {
                // If the caller also wants to switch to a new configuration,
                // do so now.  This allows a clean switch, as we are waiting
                // for the current activity to pause (so we will not destroy
                // it), and have not yet started the next activity.

                // 更新configuration
                mService.updateConfigurationLocked(config, null, false, false);
            }

            Binder.restoreCallingIdentity(origId);

            if (outResult != null) {  // 回数据给caller
                outResult.result = res;
                if (res == ActivityManager.START_SUCCESS) { // 启动成功
                    mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            mService.wait();  // 等待新的activity启动
                        } catch (InterruptedException e) {
                        }
                    } while (!outResult.timeout && outResult.who == null);

                // 后台进程切换到前台
                } else if (res == ActivityManager.START_TASK_TO_FRONT) { 
                    ActivityRecord r = this.topRunningActivityLocked(null);
                    if (r.nowVisible) {
                        outResult.timeout = false;
                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
                        outResult.totalTime = 0;
                    } else {
                        outResult.thisTime = SystemClock.uptimeMillis();
                        mWaitingActivityVisible.add(outResult);
                        do {
                            try {
                                mService.wait();  // 等待新的activity启动
                            } catch (InterruptedException e) {
                            }
                        } while (!outResult.timeout && outResult.who == null);
                    }
                }
            }

            return res;
        }
    }

ActivityStack会先检查intent的合法性,然后解析activity的信息。如果activity对应的进程已经启动过,则修正启动caller的信息。然后调用了startActivityLocked(),最后如果需要返回数据,则wait等待新的activity的启动结果。

    final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
            String resultWho, int requestCode,
            int callingPid, int callingUid, int startFlags, Bundle options,
            boolean componentSpecified, ActivityRecord[] outActivity) {

        int err = ActivityManager.START_SUCCESS;

        // 。。。。省略,获取caller信息

        int launchFlags = intent.getFlags();

        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
                && sourceRecord != null) {
            // Transfer the result target from the source activity to the new
            // one being started, including any failures.
            if (requestCode >= 0) {
                ActivityOptions.abort(options);
                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
            }

            // 。。。。省略,修正result信息
        }

        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
            // We couldn't find a class that can handle the given Intent.
            // That's the end of that!
            err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }

        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
            // We couldn't find the specific class specified in the Intent.
            // Also the end of the line.
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }

        if (err != ActivityManager.START_SUCCESS) {
            if (resultRecord != null) {
                // 将启动错误返回给caller,最终通过ApplicationThread的scheduleSendResult()通知到activity
                sendActivityResultLocked(-1,
                    resultRecord, resultWho, requestCode,
                    Activity.RESULT_CANCELED, null);
            }
            mDismissKeyguardOnNextActivity = false;
            ActivityOptions.abort(options);
            return err;
        }

        // 权限检查
        final int startAnyPerm = mService.checkPermission(
                START_ANY_ACTIVITY, callingPid, callingUid);
        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
            if (resultRecord != null) {
                // 返回错误
                sendActivityResultLocked(-1,
                    resultRecord, resultWho, requestCode,
                    Activity.RESULT_CANCELED, null);
            }

            throw new SecurityException(msg);
        }

        ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
                intent, resolvedType, aInfo, mService.mConfiguration,
                resultRecord, resultWho, requestCode, componentSpecified);
        if (outActivity != null) {
            outActivity[0] = r;
        }

        err = startActivityUncheckedLocked(r, sourceRecord,
                startFlags, true, options);

        return err;
    }

7、总结

Instrumentation作为中间者(Activity的成员变量),用来监控activity和系统的交互。
Instrumentation通过BpActivityManager(ActivityManagerNative)发送命令到ApplicationManagerService(发送命令时,附带了binder对象),而ApplicationManagerService则通过BpApplicationThread(ApplicationThreadNative)控制到ActivityThread,再控制到Activity。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值