主Activity(Root Activity)的启动流程

Activity启动流程源码分析中我讲了就是普通的启动Activity,但是其实他们的启动过程基本是差不多,要说区别就是启动主Activity是需要创建进程的Application和很多的初始化的操作。

public static void main(String[] args) {
    //在当前线程创建Looper,也就是主线程的Looper
    Looper.prepareMainLooper();

    //c创建ActivityThread
    ActivityThread thread = new ActivityThread();
    //依附mAppThread给AMS
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    //开始消息循环
    Looper.loop();
}

接着看 thread.attach(false);

  private void attach(boolean system) {

        //依附mAppThread给AMS,也就是把ApplicationThread客户端代理传给了AMS,之后又AMS通过调用AppThread的各种
        //scheduleXX方法调度四大组件的生命周期方法
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            //依附AppThread给AMS,其中ApplicationThread是IApplicationThread的代理类,实际上是调用了AMS的attachApplication
            mgr.attachApplication(mAppThread);

        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

//ActivityManagerNative

public abstract class ActivityManagerNative extends Binder implements IActivityManager {
        //省略很代码.................

    case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            //拿到ApplicationThread的代理
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                //调用AMS自己的方法
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }
        //省略很代码.................
}

为了简洁我删了很多代码,上面代码知道,首先拿到AMS的服务代理,之后将ApplicationThread作为参数传进去,那肯定会回调ActivityManagerNative的onTransact把ApplicationThread实例传给AMS服务。其实ApplicationThread是Client端的Binder,里面有操作scheduleXX方法处理四大组件的生命周期方法,所以AMS服务想要调用启动组件,那就必须持有ApplicationThread的实例,如调用ApplicationThread的scheduleLaunchActivity方法,最后在scheduleLaunchActivity方法中sendMessage方法发送消息,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);
    }

上面代码知道系统服务启动Activity并不是发送消息过来的,而是通过调用ApplicationThread的方法来完成这些过程的,ApplicationThread代码如下。

//IApplicationThread

public interface IApplicationThread extends IInterface {
                //省略很多代码.................
    }

//ApplicationThreadNative

public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {
 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
    {
        //省略很多代码.................
     
        //实际上是调用了ApplicationThreadNative的子类ApplicationThread,在ActivityThread中定义,反正他仅仅是做和Binder相关的处理,基本的业务交个子类Application处理
        scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                notResumed, isForward, profilerInfo);
        return true;
    }       

    //省略很多代码.................


    }

 }

//ActivityThread.ApplicationThread

//Client端的Binder
private class ApplicationThread extends ApplicationThreadNative {


    //省略很多代码.................


     public final void schedulePauseActivity(IBinder token, boolean finished,
                                            boolean userLeaving, int configChanges, boolean dontReport) {
        int seq = getLifecycleSeq();
        if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
                + " operation received seq: " + seq);

        //发送消息给H类,是以Handler类,ActivityThread.H类
        sendMessage(
                finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                token,
                (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                configChanges,
                seq);
    }


    //省略很多代码.................

}

ApplicationThread是ActivityThread的内部类,它继承了ApplicationThreadNative,而ApplicationThreadNative则继承了Binder类和实现了IApplicationThread接口,足以证明ApplicationThreadNative是Binder类,而ApplicationThreadNative是抽象类它仅仅处理基本的Binder操作,其余的交给的它的子类ApplicationThread。

接着在ActivityThread把ApplicationThread的代理传进AMS中,接着调用MAS的attachApplication方法,代码如下:

@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

这里没什么好说的,就是获取pid,接着调用attachApplicationLocked方法,代码如下:

     private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {


    //省略很多代码.................

            //绑定进程,还会创建Application
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
                getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked());

     //省略很多代码.................


    if (normalMode) {
        try {

            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    }

这里也是省略很多代码,之后回调到ApplicationThread的bindApplication方法,代码如下:

    public final void bindApplication(String processName, ApplicationInfo appInfo,
                                      List<ProviderInfo> providers, ComponentName instrumentationName,
                                      ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                                      IInstrumentationWatcher instrumentationWatcher,
                                      IUiAutomationConnection instrumentationUiConnection, int debugMode,
                                      boolean enableBinderTracking, boolean trackAllocation,
                                      boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                                      CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {

        if (services != null) {
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }
        sendMessage(H.BIND_APPLICATION, data);
    }

然后调用handleBindApplication方法,代码如下:

private void handleBindApplication(AppBindData data) {

Application app = data.info.makeApplication(data.restrictedBackupMode, null);
}

可以知道在handleBindApplication中有调用LoadedApk的makeApplication方法创建Application,代码如下:

public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {


    ................

    //如果app已经存在了,就直接返回
    if (mApplication != null) {
        return mApplication;
    }

    ............

    Application app = null;

    ......................

    try {
        java.lang.ClassLoader cl = getClassLoader();
        //创建AppConte
        ContextImpl appContext = ContextImpl.createAppContex(mActivityThread, this);
        //调用Instrumentation的newApplication方法通过反射创建Application,并且调用Applciation的attach方法
        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
      ....................
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    ...............

    if (instrumentation != null) {
        try {
            //调用Application的onCreate方法
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            .............
        }
    }

    return app;
}

在makeApplication方法中,首先判断app是否已经存在了,存在就直接返回app实例,否则通过调用Instrumentation的newApplication方法,反射创建Application,并且调用Applciation的attach方法反射创建Application,最后在LoadedApk的makeApplication方法中调用instrumentation.callApplicationOnCreate(app),也就是直接调用app.onCreate(),所以上面讲解了Application启动的过程,所以在回到AMS中的attachApplicationLocked方法。

    private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {


    //省略很多代码.................

            //绑定进程,还会创建Application
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
                getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked());

     //省略很多代码.................


    if (normalMode) {
        try {
            //注释A
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    }

就是当绑定application结束,即bindApplication方法处理完成,最后到注释A的位置调用了ActivityStackSupervisor的attachApplicationLocked方法,代码如下:

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            //栈顶activity
            ActivityRecord hr = stack.topRunningActivityLocked();
            if (hr != null) {
                if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) {
                    try {
                        if (realStartActivityLocked(hr, app, true, true)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                      ................
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

上面查找栈顶的Activity,最后又ActivityStackSupervisor的realStartActivityLocked方法启动Activity了,代码如下:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {

                ...................

     //调度ApplicationThread,启动Activity
        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);

                ....................


}

可以看到在ActivityStackSupervisor.realStartActivityLocked方法中,直接就调用ApplicationThread的scheduleLaunchActivity方法,顾名思义,启动Activity。

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

在ApplicationThread.scheduleLaunchActivity方法中有调用sendMessage(H.LAUNCH_ACTIVITY, r)方法,代码如下:

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
 
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

在sendMessage方法中调用 mH.sendMessage(msg),其实mH是Handler的子类,发消息到handleMessage方法中,代码如下:

public void handleMessage(Message msg) {

    ..........

    switch (msg.what) {
            case LAUNCH_ACTIVITY: {
              
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
                //最终启动Activity
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
              
            }

    ...............
}

在handleMessage方法中有调用ActivityThread的handleLaunchActivity方法去启动Activity,代码如下:

//运行Activity开始的地方,就是Activity的生命周期的开始
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

    // 在创建Activity之前初始化,实际上是创建了WMS的代理,即在WindowManagerGlobal管理者WMS
    WindowManagerGlobal.initialize();
    //处理启动Activity
    Activity a = performLaunchActivity(r, customIntent);

    ........................

    if (a != null) {
        //执行onResume方法
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

        ..............

    } else {
      .................
    }
}

之后有调用performLaunchActivity方法,启动Activity,代码如下:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;

  ................


    //解析intent数据
    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);
    }

    //通过反射创建Activity实例
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.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) {
     ............
    }

    try {

        //创建Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);


        if (activity != null) {
            //这里面做创建了PhoneWindow
            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);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }

            r.lastNonConfigurationInstances = null;

            //标志activity还未开始
            activity.mStartedActivity = false;

            //获取主题资源id
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                //为activity设置主题
                activity.setTheme(theme);
            }

            activity.mCalled = false;

            //指示如何在重新启动时保留此activity,以便在“最近”列表中进行还原的值,这里回调onCreate方法,将进行setContentView
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }

           ...........

            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
                //执行onStart方法
                activity.performStart();
                r.stopped = false;
            }

            if (!r.activity.mFinished) {
                //看看有没有持久化的数据,比如由于系统内存紧张而回收activity
                if (r.isPersistable()) {
                    if (r.state != null || r.persistentState != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }

            if (!r.activity.mFinished) {
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                } else {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                }
                .................
            }
        }
        r.paused = true;
        mActivities.put(r.token, r);

    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
       ..............
    }

    return activity;
}

在performLaunchActivity方法中,首先解析intent数据,获取启动Activity的数据,然后调用Instrumentation.newActivity方法通过反射创建Activity实例,接着调用Activity的activity.attach方法,创建PhoneWindow并将PhoneWindow实例依附到WindowManager,接着在performLaunchActivity方法调用Instrumentation.callActivityOnCreate方法间接回调Activity的生命周期方法onCreate,紧接着 activity.performStart()回调Activity的生命周期方法onStart,所以再回到handleLaunchActivity方法中直接调用handleResumeActivity方法去运行Activity,也就是Activity的onResume方法,这里就不展开讲,你只需要知道这里就是Activity运行了就行,因为handleResumeActivity这个下一篇会讲,这里会涉及View的绘制相关的知识,所以暂时不讲。

总结

实际上整个流程由ActivityThread.main方法开始,因为是应用进程为启动,所以需要去创建Applicatio并绑定到ActivityThread也就是主线程,紧接着进程信息初始化完成之后,就进入启动根Activity(Root Activity),当Activity启动完成之后就开始执行该Activity的生命周期,值得说的是,在Activity.attach方法中,将AppThread依附给AMS,其中ApplicationThread是IApplicationThread的代理类,实际上是调用了AMS的attachApplication方法,并且ApplicationThread是Client的Binder,负责接收AMS调用分别做不同的处理,比如:启动Activity以及Activity的生命周期方法,就是说AMS服务是系统引导服务,系统进程,所以AMS想要通知Client端的做处理,就需要通过Binder做跨进程操作,所以ApplicationThread作为Client端的Binder,是Binder的Service端,AMS远程调用ApplicationThread的方法,然后ApplicationThread通过Activity内部类H发消息去做处理。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容