美文网首页
Activity启动流程源码分析

Activity启动流程源码分析

作者: 有没有口罩给我一个 | 来源:发表于2019-06-02 23:46 被阅读0次

    Android窗口机制之由setContentView引发的Window,PhoneWindow,DecorView源码理解

    Activity启动流程源码分析

    简单分析Binder工作机制

    开始之前看一下从Luanch启动一个主Activity的流程图,也就是从ActivityThread的main方法开始,都知道App的启动就是从ActivityThread的main方法开始:


    app启动流程.png

    也就说在从Luanch开始调用了ActivityThread的main方法,当然在这之前还有很多的初始化操作,暂时不分析,从main方法开始,其中包括创建Application和进程信息的初始化操作,当然这是和普通的启动Activity有一定的区别。

    此文章基于AIP25源码,既然我们Activity启动流程源码分析,那么在开始之前我们应该认识一下与Activity启动相关的类,先看类图:

    activity启动流程相关类图.png

    图画的有点乱,但不影响我们分析Activity启动流程,可以看到图中涉及到的类并不多,其中涉及了Binder的相关的知识点,毕竟应用需要和系统服务进程交互,这是Android给我们提供的跨进程通信的机制,当然如果对AIDL和Binder不是很熟悉的话,可以去脑补一下。

    • IBinder 是一个接口,Binder类实现了它,而Binder是一个抽象类。

    • IInterface 是一个接口,AIDL接口必须实现它。

    • asInterface() 从BinderProxy获取一个IInterface对象(Stub$Proxy);

    • asBinder() 获取IInteface接口所关联的得BinderProxy;

    • Binder是一个抽象类实现了IBinder,Binder是Android中跨进程通讯的方式,AIDL是最常用的夸进程通讯方式,它是对Binder的封装,AIDL是App和系统基础宁通信的基石,消息机制和AIDL构成Android系统中最核心的两个部分,Binder会和一个BinderProxy对象相关联,

    • IActivityManager 用于与AMS交互的系统级私有API, 提供了从应用程序返回活动管理器的调用。简单说就是定义操作四大组件相关的的API。

    • ActivityManagerNative 继承了Binder类并且实现IActivityManager,这里的IActivityManager实际上和ActivityManager并没有太大的联系,不过ActivityManager里面有些操作会用到ActivityManagerNative ,而ActivityManagerNative 是操作Activity的主要类,可以这么说ActivityManager封装了ActivityManagerNative 的部分功能。

    • ActivityManager它主要对运行中的Activity进行管理,这些管理工作并不是由ActivityManager来处理的, 而是交由AMS来处理,ActivityManager中的方法会通过ActivityManagerNative(简称AMN)的getDefault方法来得到ActivityManagerProxy(简称AMP),通过AMP就可以和AMN进行通信,而AMN是一个抽象类,它会将功能交由它的子类AMS来处理,所以AMP就是AMS的代理类,这句话一定要记住。AMS作为系统核心服务,很多API是不会暴露给ActivityManager的,因此ActivityManager并不算是AMS家族一份子。

    • ActivityManagerService 作为系统核心服务,并且它继承了ActivityManagerNative,AMS其实是一个Binder类,既然ActivityManagerNative是抽象基类,所以基本操作已经做完了,其余就交给子类完成,比如:AMN做了Binder的机制的操作,而AMS即不需要再做这些,只要关注自己的业务就行了,这样的好处是职责明确。

    • IApplicationThread、ApplicationThreadNative、ApplicationThreadProxy和ApplicationThread,ApplicationThread是ActivityThread的内部类,其实这些的作用是和AMS族的机制是一样的,比如IApplicationThread,定义了基本的接口,而其他的就是Binder相关的,最后ApplicationThread也是ApplicationThreadNative的子类,ApplicationThreadNative主要负责Binder相关的处理,而ApplicationThread则做自己的逻辑,即:ApplicationThread是Client的Bider,服务如果要操作Client端需要通过ApplicationThread去操作,毕竟是夸进程的通讯嘛,在捋一下,IApplicationThread继承了IInterface接口,它实现类是ApplicationThreadNative继承了Binder类,他是一个抽象类,它仅仅只做了和Binder相关的操作,而 它的子类是ApplicationThread,就是说如果系统服务如AMS想要通知启动Activity,那就要调用ApplicationThread客户端的Binder通信。

    • Instrumentation 监控应用程序和系统服务的交互

    给大家先讲解这些类,是给大家有个印象,看下去就不会很蒙圈接下来就正是开始吧,先从Activity.startActivity开始。

    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }
    

    startActivity根据options选择调用startActivityForResult函数,其中第二个参数requestCode为-1,表示Launcher不需要知道Activity启动的结果,也就是当requestCode>0时,当activity退出时会回调onActivityResult方法,startActivityForResult函数的代码如下所示。

     public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
    
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
    
        //............
        } else {
          //..........
        }
    }
    

    为了简介我把部分代码删掉,只留下比较重要的,mParent是Activity类型的,表示当前Activity的父类。因为当前的Activity还没有创建出来,mParent == null成立。接着调用Instrumentation的execStartActivity方法, Instrumentation主要用来监控应用程序和系统服务的交互。

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
    
        //注意这里contextThread,是从Activity中传进来的ApplicationThread,后面就是使用它发送消息启动Activity的
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
    
            //获取AMS的代理对象
            IActivityManager aDefault = ActivityManagerNative.getDefault();
    
            //调用代理对象的startActivity,执行transact执行RPC操作
            int result = aDefault.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来获取ActivityManageService(后面简称为AMS)的代理对象AMN,接着调用它的startActivity方法。首先我们先来查看ActivityManagerNative的getDefault方法做了什么:

     static public IActivityManager getDefault() {
        return gDefault.get();
    }
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
    
            //通过名称获取一个service的应用,这里就是AMS
            IBinder b = ServiceManager.getService("activity");//1
            //返回的是一个持有AMS的引用的代理对象
            IActivityManager am = asInterface(b);//2
            return am;
        }
    };
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        //AMS
        IActivityManager in = (IActivityManager) obj.queryLocalInterface(descriptor);
        if (in != null) {
            //返回当前ActivityManagerNative
            return in;
        }
        //服务端的代理,返回ActivityManagerProxy,执行transat
        //将返回的AMS的封装成代理
        return new ActivityManagerProxy(obj);
    }
    

    getDefault方法调用了gDefault的get方法,gDefault 是一个Singleton类的实例。在1处获取名子为”activity”的Service引用,也就是IBinder类型的ActivityManagerService的引用。接着在2处将它封装成ActivityManagerProxy类型对象,getService方法是有缓存的,此后调用ActivityManagerNative的getDefault方法就会直接获得AMS的代理AMP对象。
    回到Instrumentation类的execStartActivity方法中,从上面得知就是调用AMP的startActivity,其中AMP是ActivityManagerNative的内部类,代码如下所示。

    /**
     * 首先会将传入的参数写入到Parcel类型的data中。
     * 通过IBinder类型对象mRemote(AMS的引用)向服务端的AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。
     * 那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用AMN的onTransact方法,onTransact中会调用AMS的startActivity方法,
     */
    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
                             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                             int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
    
    
        //首先会将传入的参数写入到Parcel类型的data中。
        // 在注释1处通过IBinder类型对象mRemote向AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。
        // 那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,
        // 最终会调用ActivityManagerNative的onTransact方法中执行
    
        //发起RPC过程 ,这里是会阻塞的,等待transact结束
    
    
        //实际上会调用ActivityManagerService的onTransact,之后又回调ActivityManagerNative的onTransact,然后在onTransact中有调用ActivityManagerService的startActivity方法
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//1
        //  接着从_reply中取出RPC过程返回的结果
        reply.readException();
        //  最后返回_reply中的数据
        int result = reply.readInt();
    
        reply.recycle();
        data.recycle();
        return result;
    }
    

    其实注释写得也是还可以的,首先会将传入的参数写入到Parcel类型的data中,大家知道Binder支持的类型也就那几种。在1处通过IBinder类型对象mRemote向AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用ActivityManagerNative的onTransact方法中执行。如下所示。

     @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
    
            //通过code知道client调用的目标方法
            case START_ACTIVITY_TRANSACTION: {
                data.enforceInterface(IActivityManager.descriptor);
                IBinder b = data.readStrongBinder();
    
    
                //这行代码也是获取到了持有ApplicationThread引用的代理对象,然后传给AMS,以便启动Activity,如:scheduleLaunchActivity
                IApplicationThread app = ApplicationThreadNative.asInterface(b);
    
    
                //获取Client传过来的数据
                String callingPackage = data.readString();
                Intent intent = Intent.CREATOR.createFromParcel(data);
                ..........................................
                //调用ActivityNamagerService,具体实现在AMS中,启动ACtivity
                int result = startActivity(app, callingPackage, intent, resolvedType,
                        resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
    
                //启动完成将结果写入reply,通过Client的启动activity的结果
                reply.writeNoException();
                reply.writeInt(result);
                return true;
            }
    

    }

    onTransact中会调用AMS的startActivity方法不是AMN中的startActivity了,我刚开始看得时候就是这想的哈哈,如下所示。

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

    在AMS中startActivity有再次调用startActivityAsUser方法,startActivityAsUser方法中又调用了mActivityStarter的startActivityMayWait方法:这里的调用关系非常多,我直接写得简洁的,就看重点:AMS.startActivity->AMS.startActivityAsUser
    ->ActivityStack.startActivityMayWait->ActivityStack.startActivityLocked
    ->ActivityStack.doPendingActivityLaunchesLocked
    ->ActivityStack.startActivityUnchecked
    ->ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
    ->ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
    ->ActivityStack.resumeTopActivityUncheckedLocked
    ->ActivityStack.resumeTopActivityInnerLocked
    ->ActivityStackSupervisor.startSpecificActivityLocked
    ->ActivityStackSupervisor.realStartActivityLocked

    最后看看ActivityStackSupervisor.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),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
    
    ...................
    
    return true;
    }
    

    这里的 app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口,所以我们抓重点,去看看那ActivityThread的内部类ApplicationThread的scheduleLaunchActivity方法,代码如下所示:

        //ams最终回调这个方法启动Activity
        @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();
    
            //发送消息启动Activity
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
    

    为了简介我删掉了很多无用的代码,所以AMS最终调用ActivityThread的内部类ApplicationThread的scheduleLaunchActivity方法sendMessage发消息启动Activity,sendMessage方法如下:

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

    可以看到最终调用mH的sendMessage,mH是Activity的内部类H,继承了Handler,看看handleMesage:

     public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    //最终启动Activity
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
    
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                }
                break;
        .......................
    }
    

    最终调用了handleLaunchActivity。代码如下所示:

     //运行Activity开始的地方,就是Activity的生命周期的开始
    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);
    
        if (localLOGV) Slog.v(
                TAG, "Handling launch of " + r);
    
        // Initialize before creating the activity
        WindowManagerGlobal.initialize();
    
        Activity a = performLaunchActivity(r, customIntent);
    
        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
    
            if (!r.activity.mFinished && r.startsNotResumed) {
                // The activity manager actually wants this one to start out paused, because it
                // needs to be visible but isn't in the foreground. We accomplish this by going
                // through the normal startup (because activities expect to go through onResume()
                // the first time they run, before their window is displayed), and then pausing it.
                // However, in this case we do -not- need to do the full pause cycle (of freezing
                // and such) because the activity manager assumes it can just retain the current
                // state it has.
                performPauseActivityIfNeeded(r, reason);
    
                // We need to keep around the original state, in case we need to be created again.
                // But we only do this for pre-Honeycomb apps, which always save their state when
                // pausing, so we can not have them save their state when restarting from a paused
                // state. For HC and later, we want to (and can) let the state be saved as the
                // normal part of stopping the activity.
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManagerNative.getDefault()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }
    

    到这一步实际上Activity的启动基本就结束了,接下来就是初始化Activity的窗口主题和视图,这些下篇文章讲解,最后看一下时序图,会更好理解,第一次画图,很丑:

    activity启动流程.png

    说一下代理模式:代理模式就是多一个代理类出来,替原对象进行一些操作,比如:ActivityManagerNative的代理类ActivityManagerProxy而它们俩都实现了IActivityManager接口,ActivityManagerService是ActivityManagerNative的子类,所以ActivityManagerProxy代理的是ActivityManagerService,在系统服务中大量使用了代理模式去实现Binder的通信,Android系统涉及到Binder的都大量用到了静态代理。

    最后,我觉得看完Activity启动的流程,再看Android窗口机制之由setContentView引发的Window,PhoneWindow,DecorView源码理解这篇文章,基本上从Activity启动流程到Activity的初始化和窗口创建以及视图的填充基都会更加的深入。

    相关文章

      网友评论

          本文标题:Activity启动流程源码分析

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