美文网首页
源码探探之StartActivity(一)

源码探探之StartActivity(一)

作者: AaronXee | 来源:发表于2017-10-18 10:08 被阅读0次

    源码基于API 26

    startActivity()上车

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
    

    没什么好说的

    //启动一个activity不需要返回值
    //如果context之外调用startActivity(),需要给intent添加{@link Intent#FLAG_ACTIVITY_NEW_TASK}
    //@param options 附加的选项指示如果启动activity
    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            //可重写该方法兼容应用需求
            startActivityForResult(intent, -1);
        }
    }
    

    可重写该方法,参考FragmentActivity

    //If requestCode >= 0, this code will be returned in onActivityResult() when the activity exits.
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }
    

    最终执行该方法

    //启动一个activity在finish()会返回一个结果在onActivityResult()中
    //如果在onCreate()/onResume()方法中调用该方法,window不显示界面直到该方法返回结果
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        //父activity一般为空
        if (mParent == null) {
            //通过ActivityOptions帮助类生成一个bundle,指示该如何启动该activity
            options = transferSpringboardActivityOptions(options);
            //Instrumentation基类启动Activity
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            //返回结果
            if (ar != null) {
                //最终会执行Activity的onActivityResult()
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                //当接收到返回的结果了启动的activity才会显示
                mStartedActivity = true;
            }
            //取消输入并开始activity退出动画
            cancelInputsAndStartExitTransition(options);
        } else {
            //不考虑mParent不为null的情况,远古级方法,不采用了
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
    

    执行Instrumentation的execStartActivity(),Instrumentation起着监控系统和应用的作用

    //target:源activity
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        //获取当前内容索引,不重写onProvideReferrer()返回null
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            //不为null添加至intent
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        //activity监视器
        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并离开当前进程
            intent.prepareToLeaveProcess(who);
            //本地activityManager启动activity
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            //检查启动activity返回结果,抛出异常
            checkStartActivityResult(result, intent);
            //跨进程异常
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
    

    ActivityManagerNative.getDefault()获取IActivityManager接口,调用startActivity()方法。
    事实上是ServiceManager.getService("activity"), 即获取ActivityManagerService(AMS)并通过Binder远程调用ActivityManagerService类的startActivity()方法。

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            //获取activityService
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            //返回service代理对象
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        //通过binder获取AMS
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        //代理obj其实就是AMS
        return new ActivityManagerProxy(obj);
    }
    

    IAvityManager对所有运行着的Activity交互提供了接口,ActivityMangerNative实现了IActivityManager接口,IActivityManger的大多数功能都是调用了ActivityManagerNative类接口来完成的,而AMS继承了ActivityMangerNative。
    ActivityMangerNative作为IActivityManger和AMS的中间类,解耦了两者间的依赖,所有对AMS的访问都转换成了对ActivityMangerNative的代理类ActivityMangerProxy的访问。

    从这里的getDefault().startActivity()开始从本应用通过binder跨进程调用AMS的方法

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }
    @Override
    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) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null);
    }
    

    ActivityStarter类负责处理启动activity之前的准备工作,包括Activity的Intent和Flags的逻辑, 还有管理Stack和TaskRecord.
    ActivityStarter类的调用流程:

    • ActivityStarter#startActivityMayWait(根据Intent获取Activity的启动信息(ResolveInfo和ActivityInfo)
    • ActivityStarter#startActivityLocked(创建ActivityRecord, 含有Activity的核心信息)
    • ActivityStarter#startActivityUnchecked(根据启动的Flag信息, 设置TaskRecord)

    接着执行ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked()方法

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        return false;
    }
    

    ActivityStackSupervisor类与ActivityStack类配合使用. ActivityStackSupervisor负责管理Task和Stack, 而ActivityStack负责管理在Stack和Task中的Activity

    ActivityStackSupervisor类与ActivityStack类的调用流程:

    • ActivityStackSupervisor#resumeFocusedStackTopActivityLocked

    • ActivityStack#resumeTopActivityUncheckedLocked

    • ActivityStack#resumeTopActivityInnerLocked(根据ActivityRecord和ActivityOptions完成Activity的切换, 移至栈顶)

    • ActivityStackSupervisor#startSpecificActivityLocked

    • ActivityStackSupervisor#realStartActivityLocked(真正启动activity)

       final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
               boolean andResume, boolean checkConfig) throws RemoteException {
           ...
           app.forceProcessStateUpTo(mService.mTopProcessState);
           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);
           ...
       }
      

    最后由ActivityThread中的ApplicationThread调用scheduleLaunchActivity完成Activity的真正启动。
    这里的thread是IApplicationThread接口,该接口继承了IInterface接口,实现方法asBinder()方法作为binder通信。

    这里通过binder跨进程由系统进程调用应用进程启动activity

    相关文章

      网友评论

          本文标题:源码探探之StartActivity(一)

          本文链接:https://www.haomeiwen.com/subject/tassuxtx.html