Activity的启动流程源码解析

         Activity的startActivity有好几种重载方式,但是他们最终都会调用startActivityForResult方法。

     public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {    //判断是ActivityGroup中是否包含子Activity
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,//注意此处的mManinThread.getApplicationThread(),注意thread的传递
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            final View decor = mWindow != null ? mWindow.peekDecorView() : null;
            if (decor != null) {
                decor.cancelPendingInputEvents();
            }
            // 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);
            }
        }
        if (options != null && !isTopOfTask()) {
            mActivityTransitionState.startExitOutTransition(this, options);
        }
    }
    当程序进入该方法后,我们首先会判断  mParent是否为空。mParent代表的是ActivityGroup。因为ActivityGroup在以前是用来作为在Activity中嵌套多个子Activity时所使用的容器,但是在API12以后的版本已经被废弃,改为用Fragment替代。所以我们只需要看mParent == null 中的逻辑代码即可。

当进去程序进行下去,必定会走mInstrumentation.execStartActivity()方法:

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        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()    //ActivityManagerNative.getDefault()是一个IActivityManager类型的Binder对象
               .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);</span>
            checkStartActivityResult(result, intent);  //检查启动Activity的结果,当Activity无法正常启动时,抛出异常信息
        } catch (RemoteException e) {
        }
        return null;
    }
    从上面红色表示的代码中我们可以看出,启动Activity真正的实现是由ActivityManagerNative.getDefault()的startActivity()来完成的。ActivityManagerNative类是继承自Binder并实现ActivityManager类中的Binder接口方法。所以,ActivityManagerNative就是一个Binder。这里我们需要注意:由于ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象,他又一个具体的实现类:ActivityManagerService 。

   ActivityManagerService类是Activity管理的核心,他拥有一个自己独立的进程。   当我们调用ActivityManagerNative.getDefault()方法的时候,其实是调用了Singleton这个单例的封装类的get方法来初始化ActivityManagerService这个Binder对象。所以Activity启动的真正实现是在ActivityManagerService类中进行的。 

     Singleton类的实现和getDefault方法代码如下:

    static public IActivityManager getDefault() {
        return gDefault.get();
    }
    public abstract class Singleton<T> {
       private T mInstance;
   
       protected abstract T create();

       public final T get() {
           synchronized (this) {
               if (mInstance == null) {
                   mInstance = create();
               }
               return mInstance;
           }
       }
   }

 

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {        //实现了create构造方法
            IBinder b = ServiceManager.getService("activity");    //通过ServiceManager的getServive方法来创建ActivityManagerService实例对象
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

 当ActivityManagerService实例化成功之后,会调用它的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 options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            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 options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, userId, null, null);
    }
   从以上代码中我们可以看到,startActivity()方法中调用了startActivityAsUser()方法,最后则调用了ActivityStackSupervisor类中的starActivityMayWait()方法。

在该类中,经过了几次方法调用starActivityMayWait()->startActivityLocked()->startActivityUncheckedLocked()  。最后,startActivityUncheckedLocked()  方法中调用了

ActivityStack类中的resumeTopActivitiesLocked()方法。所以,经过这一系列的方法调用,最终这个启动过程从ActivityStackSupervisor转移到了ActivityStack类中。

   当通过调用resumeTopActivitiesLocked()方法传递到ActivityStack类之后,又进行了一系列的方法调用resumeTopActivitiesLocked()->resumTopActivityInnerLocked()->

ActivityStackSupervisor()->realStartActivityLocked()。

         由于流程过于繁琐,所以我制作了一个流程图供更直观的学习,如下:

       

  
  这里我们需要说一下realStartActivityLocked()方法里面的一段代码:

    

              app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
                    results, newIntents, !andResume, mService.isNextTransitionForward(),
                    profilerInfo);
   此处的app.thread 就是前面需要注意的那个mMainThread.getApplicationThread()。ApplicationThread是ActivityThread类当中的一个内部类,他是IApplicationThread接口的 最终实现类(中间还有一个抽象类ApplicationThreadNative)。这里需要介绍一下IApplicationThread接口:他继承自IInterface接口,因此是一个Binder类型。其内部包含了大量的启动、停止Activity的接口方法,同时也包含了启动和停止服务的接口方法。因为ApplicationThread实现了IApplicationThread,所以其内部可完成Activity以及Sercvice启动和停止相关的功能。




通过这一系列调用和事件传递,我们最后会发现,Activity的启动过程,最终是在ApplicationThread中进行,而ApplicationThread则是调用其中的scheduleLaunchActivity()方法来启动Activity。

    

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

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            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);   //此处发送Activity启动消息给名为H的handler来处理
        }

  通过代码我们发现,ApplicationThread类调用scheduleLaunchActivity()方法来发送消息给名为H的handler,下面为handler对事件的处理:

 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;
 而handler又调用了handlerLaunchActivity方法来启动,代码如下:

   

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // 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);

        Activity a = performLaunchActivity(r, customIntent);   //创建Activity

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
           handleResumeActivity(r.token, false, r.isForward,    //调用activity的onResume方法
                    !r.activity.mFinished && !r.startsNotResumed);

      ...
        }
    }

    最终我们发现,是performLaunchActivity()方法来完成Activity的创建,并通过handleResumeActivity方法来启动Activity的onResume生命周期方法。 

    performLaunchActivity()方法主要完成以下几件事:

     1.从ActivityClientRecord中获取启动的Activity的组件信息。

      2.通过Instrumention的newActivity()方法使用类加载器创建Activity对象

     3.通过LoadedApk的makeApplication()方法来尝试创建Application对象

     4.创建ContextImpl对象并通过Activity的attach()方法来完成一些重要数据的初始化

     5.调用Activity的onCreate()方法

下面来进行一一介绍

       1.从ActivityClientRecord中获取启动的Activity的组件信息。

     

        ActivityInfo aInfo = r.activityInfo;    //获取Activity的组件信息
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        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);
        }

   2.通过Instrumention的newActivity()方法使用类加载器创建Activity对象

     

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();     //获取类加载器
            activity = mInstrumentation.newActivity(                       //调用newActivity方法来创建对象
                    cl, component.getClassName(), r.intent);
            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);
            }
        }
          调用的newActivity方法如下:

  

    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();    //返回类加载器加载出来的Activity
    }

3.通过LoadedApk的makeApplication()方法来尝试创建Application对象

  

try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
          //调用packageInfo中的makeApplication方法来创建Application
          ...
        } catch (SuperNotCalledException e) {
            throw e;

        }

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {               //application的单例所在
            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(    //我们会发现Application也是通过类加载器来创建的
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }

        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
                .getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }

            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }

        return app;
    }

  从上面代码我们可以看到,Application的单例实现,我们发现Application也是通过Instrumentation的类加载器来创建的。    

   当Application创建完成后,系统会通过Instrumentation的callApplicationOnCreate来调用Application的onCreate方法。   所以,Application的onCreate方法比Activity方法更快执行。


     4.创建ContextImpl对象并通过Activity的attach()方法来完成一些重要数据的初始化

 Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
               activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.voiceInteractor);
      此处的ContextIml是一个很重要的数据结构,他是Context的具体实现,Context的大部分逻辑都是由他实现。ContextImpl是通过Activity的attach方法来和Activity建立关联的。此外,在attach方法中Activity还会完成Window的创建并建立自己和Window的关联。这样,当Window接收到外部输入时间后,就可以将事件传递给Activity。


   5.调用Activity的onCreate()方法

                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
当走完这callActivityOnCreate方法后,就表示Activity已经创建成功了,所以Activity至此完成了整个启动过程。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Activity启动模式是Android应用程序中非常重要的概念,它决定了Activity的启动方式和生命周期的管理方式。在Android中,Activity启动模式主要有以下几种: 1. standard:标准模式。默认情况下,每次启动Activity时都会创建一个新实例,并放入任务栈中。如果该Activity已经存在任务栈中,则会将该Activity放到栈顶,并重新调用其onCreate()方法。 2. singleTop:栈顶复用模式。如果新启动的Activity已经存在任务栈的栈顶,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并调用其onNewIntent()方法。如果新启动的Activity不在栈顶,则会创建新实例,并将其放到任务栈的栈顶。 3. singleTask:栈内复用模式。如果新启动的Activity已经存在任务栈中,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并将其上面的Activity全部出栈,调用其onNewIntent()方法。如果新启动的Activity不存在任务栈中,则会创建新实例,并放到任务栈的栈顶。 4. singleInstance:单例模式。在一个新的任务栈中创建Activity,并且该任务栈中只有该Activity实例。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。 下面是Activity源码分析: 1. standard模式 在Activity源码中,标准模式是默认的启动模式。当我们使用startActivity()方法启动一个Activity时,会调用ActivityStackSupervisor类中的startActivityLocked()方法。在该方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会将当前Activity放到该任务栈的栈顶,并调用其onCreate()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 2. singleTop模式 当我们在Manifest文件中设置Activity的启动模式为singleTop时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈,并判断当前Activity是否在栈顶。如果在栈顶,则会调用其onNewIntent()方法。如果不在栈顶,则会创建一个新的实例,并放到该任务栈的栈顶。 3. singleTask模式 当我们在Manifest文件中设置Activity的启动模式为singleTask时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会找到该任务栈中的栈顶Activity,并将其上面的所有Activity出栈。然后将当前Activity放到该任务栈的栈顶,并调用其onNewIntent()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 4. singleInstance模式 当我们在Manifest文件中设置Activity的启动模式为singleInstance时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值