从Android 6.0源码的角度剖析Activity的启动过程

版权声明:精髓原创,欢迎转载、指正、探讨。--蒋东国 https://blog.csdn.net/AndrExpert/article/details/81488503

转载请声明出处: https://blog.csdn.net/AndrExpert/article/details/81488503

从Android 6.0源码的角度剖析Window内部机制原理文章中,我们详细剖析了Android Window的内部工作机制,了解到每一个Activity都对应着一个Window,Activity的视图(View)都是依附在Window来呈现的,Window实际是View的直接管理者。本文将在剖析Activity启动过程的基础上,详细了解下Activity的Window创建过程。

1. Activity的启动过程

 众所周知,在Android开发中如果我们需要启动一个Activity,必须是先实例化一个Intent对象,然后调用Activity的startActivity()或startActivityForResult()来实现。因此,对于Activity的启动过程,我们就从这两个方法入手。通过查看Activity源码可知,虽然startActivity()方法有多个重载,但是在这些方法中最终会调用方法startActivityForResult(),也就是说,startActivityForResult()方法是分析Activity启动过程的入口。

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

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Activity启动过程分析入口
        startActivityForResult(intent, -1);
    }
}

 Activity的startActivityForResult()方法的代码比较简单,它会根据Activity的实例mParent是否为空执行不同的逻辑,由于我们这里研究的是Activity的启动过程,所以只考虑mParent为空的情况。首先,调用Instrumentation的execStartActivity()开始执行启动Activity逻辑,该方法需要传递一个ApplicationThread实例,该ApplicationThread实质是一个Binder,其重要性我们后面会详细道来;然后,通过ActivityThread的sendActivityResult()方法,该方法会调用ApplicationThread的scheduleSendResult()方法通过消息的形式,最终调用Activity的onActivityResult(requestCode, resultCode, data)方法将启动Activity的执行结果回调。

// ApplicationThread的继承关系
private class ApplicationThread extends ApplicationThreadNative{...}
public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread{...}
//---------------------------------------------------------------        
// startActivityForResult源码
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
        // 执行Instrumentation的execStartActivity
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        // 将Activity启动结果最终通过onActivityResult回调
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }
        ...// 代码省略
    } 
}

 Instrumentation的execStartActivity方法 并没有真正实现Activity启动的逻辑,而是调用了ActivityManagerService的startActivity()方法,通过跟踪代码发现,原来ActivityManagerService是一个Binder对象,归属于系统进程,也就是说,Activity的启动过程实际上是一次IPC(Inter-Process Communication,跨进程通信);然后再调用checkStartActivityResult()方法检测最终启动的结果,并根据返回的结果作相应的反映,比如我们比较熟悉的有当被启动的Activitiy没有在AndroidManifest.xml时,系统会报”Unable to find explicit activity class … ;have you declared this activity in your AndroidManifest.xml?“异常。execStartActivity()方法源码如下:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    // 获取IApplicationThread实例
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ....
    try {
        // 执行ActivityManagerService的startActivity
        // IPC跨进程调用
        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;
}

 既然上面提到Activity的启动过程是一次IPC操作,那么我觉得在深入分析ActivityManagerService的StartActivity()之前,有必要将这其中的原理讲解下。在Instrumentation的execStartActivity方法中,主要通过ActivityManagerNative个静态方法getDefault()获得ActivityManagerService实例。通过查看源码发现,ActivityManagerNative实质是一个Binder,因为它继承于Binder和接口IActivityManager;getDefault()方法通过Default.get()返回一个IActivityManager实例,gDefault是一个单例模式匿名类对象,在它的create()方法通过ServiceManager的getSystem()方法最终返回一个ActivityManagerService对象,它继承于ActivityManagerNative,因此ActivityManagerService就是一个Binder。由于ServiceManager位于系统进程中,用于管理系统各种服务,因此,ActivityManagerService就是一种系统服务,用于管理所有Activity。基于此,Activity的启动过程,从应用进程Activity的startActivity()到系统进程的ActivityManagerService的startActivity(),就是一次IPC调用。ActivityManagerService、ActivityManagerNative 的继承关系如下:

// ActivityManagerService的继承关系
public interface IActivityManager extends IInterface{...}
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            // 获取系统服务,ActivityManagerService实例
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
    ...
   static public IActivityManager getDefault() {
    // 返回ActivityManagerSevice实例
       return gDefault.get();
   }
}
public final class ActivityManagerService extends ActivityManagerNative

 接着,我们继续分析ActivityManagerService的startActivity()方法,该方法并没有写具体的逻辑,而是直接调用ActivityManagerService的startActivityAsUser()方法,该方法继续调用ActivityStackSupervisor的startActivityMayWait()方法。从ActivityStackSupervisor的命名来看,它应该是与Activity栈有关的操作,与其相关联的还有一个类ActivityStack,它们共同完成Activity的入栈操作。考虑到Activity入栈这部分调用稍微有点复杂,这里通过流程图的形式给出在ActivityStackSupervisor和ActivityStack之间的调用过程,如下图所示,可以看到当执行到ActivityStackSupervisor的realStartActivityLocked()方法时才是真正进入到Activity的启动逻辑。
这里写图片描述
 realStartActivityLocked()方法的代码较多,但我们只需关注app.thread.scheduleLaunchActivity(...)这行代码。通过跟踪源码发现,app.thread返回一个IApplication的实例,但是IApplicationThread是一个接口,它继承于接口IInterface,scheduleLaunchActivity的具体实现必然在其子类中。果然,在源码中我们找到了抽象类ApplicationThreadNative,它不仅继承于IApplicationThread还继承于Binder,因此ApplicationThreadNative实质是一个Binder对象,对scheduleLaunchActivity()的调用也是一次IPC操作。但是遗憾的是,我们在ApplicationThreadNative类中并没有找到与Activity启动相关的功能代码,虽然在其内部类ApplicationThreadProxy(继承于ApplicationThreadNative)找到scheduleLaunchActivity(),但是它只是完成标准的IPC数据读写操作。肿么办?还记得我们在文章的开头分析Activity的startActivityForResult()方法时,传递给execStartActivity()方法的参数mMainThread.getApplicationThread()吗?mMainThread是一个ActivityThread实例,这个类对于Activity的管理来说尤其重要,从命名来看,ActivityThread应该是对应APP的主线程(UI线程),用于管理应用程序进程中主线程的执行、Activity的调度和执行、广播以及Activity管理器请求的其他操作。getApplicationThread()是ActivityThread的一个方法,它返回的就是保存在ActivityThread中的一个ApplicationThread实例,而这个ApplicationThread就是ApplicationThreadNative的子类,当然也是一个Binder对象!

// ApplcationThread的继承关系
public interface IApplicationThread extends IInterface {...}
public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {...}

public final class ActivityThread {
    private class ApplicationThread extends ApplicationThreadNative {...}
}
//---------------------------------------------------------------
final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {
        ...
        // 调用ActivityThread的scheduleLaunchActivity方法
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
        ...
}

 在ApplicationThread的scheduleLaunchActivity()方法中,该方法首先会将传入的所有参数存储到ActivityClientRecord对象中,然后调用sendMessage()使用Handler发送一个消息H.LAUNCH_ACTIVITY,其中H继承于Handler。接下来,我们在H(即Handler)的消息处理方法handleMessage()中,顺利找到了处理H.LAUNCH_ACTIVITY消息的代码段,除此之外,还包括处理诸如RELAUNCH_ACTIVITY、PAUSE_ACTIVITY、RESUME_ACTIVITY等消息。由此可见,有关Activity的生命周期等相关操作都是通过消息传递的形式切换到主线程来处理的。最终,当Handler收到H.LAUNCH_ACTIVITY消息后,会调用ActivityThread的handleLaunchActivity()方法完成最后的启动过程。

// scheduleLaunchActivity源码
@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) {
    updateProcessState(procState, false);
    ActivityClientRecord r = new ActivityClientRecord();
    r.token = token;
    r.ident = ident;
    r.intent = intent;
    r.referrer = referrer;
    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;

    r.overrideConfig = overrideConfig;
    updatePendingConfiguration(curConfig);
    // 使用Handler(H)发送LAUNCH_ACTIVITY消息
    //  在handleMessage中会调用performLaunchActivity
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

//-----------------------------------------------------------
// H的消息处理方法
public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        // 处理启动(launch) activity消息
        // 调用handleLaunchActivity
        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;
        ...
        // 处理暂停activity消息
        case PAUSE_ACTIVITY:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
            handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
                    (msg.arg1&2) != 0);
            maybeSnapshot();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        // 处理停止Activity消息
        case STOP_ACTIVITY_SHOW:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
            handleStopActivity((IBinder)msg.obj, true, msg.arg2);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        ...
}

 为了完成Activity的启动工作,handleLaunchActivity主要做了以下几件事情:
 (1) 实例化一个WindowManagerService对象,为创建Window做准备

// 实例化WindowManagerService
WindowManagerGlobal.initialize();

 (2) 调用performLaunchActivity,创建被启动的Activity实例

Activity a = performLaunchActivity(r, customIntenyt);

 关于Activity的创建过程,我们需要进入ActivityThread的performLaunchActivity()方法进入进一步分析。首先,获取Activity、Intent信息。获取Activity的基本信息,包括启动模式、主题等等,同时获取Intent的(ComponentName)组件信息; 其次,创建Activity对象。通过类加载器加载名为component.getClassName()的类,即被启动的Activity类。然后实例化出该类的对象,这个过程主要通过Instrumentation的newActivity方法实现;第三,创建Application对象。调用LoadedApk的makeApplication()方法创建Application实例,在makeApplication()方法中会先判断是否已经存在一个Application,如果已经存在则直接返回该Application。由此可见,一个应用中(假设该应用只包含一个进程)只能存在一个Application实例。第四,创建Context和Window实例,调用createBaseContextForActivity()方法创建Context上下文对象,同时调用Activity的attach()方法为Activity创建对应的Window和窗口管理器实例WindowManager。对于Activity的Window创建,我们将在下一小节详细讲解。最后,调用onCreate()方法。在Instrumatation的callActivityOnCreate()方法中,它会调用Activity的performCreate()方法,最终完成对onCreate方法的回调。至此,随着Activity的onCreate方法被回调,整个Activity的启动过程分析完毕。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 获取Activity Infomations
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    // 获取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
    // 调用Instrumentation的newActivity方法实现
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        // 执行(Activity)cl.loadClass(className).newInstance();
        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) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }

    try {
        // 使用makeApplication创建Application实例
        // 如果mApplication已经存在,则直接返回该mApplication实例
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
            // 为Activity创建上下文对象
            Context appContext = createBaseContextForActivity(r, activity);
            // 获取APP name
            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的Window对象
            // 创建窗体管理器WindowManager
            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);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            // 执行activity.performCreate方法,完成onCreate方法调用
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onCreate()");
            }
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            // 执行activity.performRestoreInstanceState方法
            // 完成onRestoreInstanceState方法调用
            if (!r.activity.mFinished) {
                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);
                }
            }
         }
     }
    ...
    return activity;
}

 (3) 当Activity实例a被创建后,说明Activity启动过程已经执行完毕。接下来,系统会根据a创建的最后结果,作相应的处理。当a!=null时,Activity被创建成功,接下来就会调用handleResumeActivity()方法,该方法会调用Activity的onResume()方法和将Activity的顶层视图DecorView添加到Window中(注:DecorView、Window等会在Activity.attach()被调用时创建);如果a==null,则Activity被创建失败,会调用ActivityManagerService的finishActivity()方法让Activity Manager结束该Activity,并清理相关的资源。

 handleLaunchActivity()源码如下:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    // 创建Activity之前,先创建WindowManagerService
    WindowManagerGlobal.initialize();
    // 执行创建Activity操作,通过类加载器
    // 执行创建或获取Application实例操作,上下文
    // 执行创建Window、WindowManager
    // 执行调用onCreate操作
    // 执行调用onRestoreSaved操作
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        // 将DecorView添加到Window中
        // 进入View绘制
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed);
        // 如果activity仍然存在且resumed状态为false,执行onPause操作
        if (!r.activity.mFinished && r.startsNotResumed) {
            try {
                r.activity.mCalled = false;
                mInstrumentation.callActivityOnPause(r.activity);          
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
                if (!r.activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPause()");
                }

            } catch (SuperNotCalledException e) {
                throw e;

            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                            "Unable to pause activity "
                            + r.intent.getComponent().toShortString()
                            + ": " + e.toString(), e);
                }
            }
            r.paused = true;
        }
    } else {
        // 如果a=null,执行finishActivity
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
        } catch (RemoteException ex) {
            // Ignore
        }
    }
}
2. Activity的Window创建过程

 从上面Activity的启动过程分析可知,Activity的Window创建是当执行到performLaunchActivity方法中的activity.attach(appContext,...)代码开始的。为了完成Activity的Window创建,Activity的attach方法主要做了以下几件事情。首先,调用attachBaseContext()方法绑定Context(上下文)到Activity;其次,通过new PhoneWindow(this)的方式实例化一个Window对象,在从Android 6.0源码的角度剖析UI界面架构文章中我们曾分析过: Window是一个抽象类,它的具体实现类为PhoneWindow,该类将DecorView作为窗体的顶层视图并封装了相关操作窗体的方法。DecorView是PhoneWindow内部类,它继承于FrameLayout,是整个窗体最顶层视图,其包括TitleView和ContentView两部分接着,调用Window的setCallback()方法向Activity注册Window状态变化事件监听器,在CallBack接口中常见的有onAttachedToWindow()、onDetachedFromWindow()等;最后,初始化与Activity相关变量,同时通过context的getSystemService(Context.WINDOW_SERVICE)方法获取一个WindowManager实例,用于管理Window与WindowManagerService之间的交互.。

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    // 设置上下文
    attachBaseContext(context);

    mFragments.attachHost(null /*parent*/);
    // 创建Activity的Window实例
    mWindow = new PhoneWindow(this);
    // 注册Window状态变化事件监听器(Window.Callback)
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }

    mUiThread = Thread.currentThread();
    // 初始化变量
    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mIdent = ident;
    mApplication = application;
    mIntent = intent;
    mReferrer = referrer;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mTitle = title;
    mParent = parent;
    mEmbeddedID = id;
    mLastNonConfigurationInstances = lastNonConfigurationInstances;
    if (voiceInteractor != null) {
        if (lastNonConfigurationInstances != null) {
            mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
        } else {
            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                    Looper.myLooper());
        }
    }

    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    // 获取Window窗体管理器WindowManager
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;
}

 至此,随着mWindow = new PhoneWindow(this)这句代码的执行,关于Activity的Window创建就基本完成了。接下来,我们在分析下Activity的视图是如何依附在Window上,以及Activity的视图何时才能被用户看见?
首先,为了将Activity的视图依附到Window,我们先需要为Activity的视图创建顶层视图DecorView,并将视图相应的布局文件添加到DecorView的mContentParent容器中。这个过程从Activity的onCreate方法开始,考虑到我们已经在从Android 6.0源码的角度剖析UI界面架构文中作了详细地剖析,这里就不再重复叙述了,给了流程图 :
这里写图片描述
其次,虽然在上一步我们将Activity的视图添加到了DecorView,但是这个时候DecorView还没有被WindowManager添加到Window中。不知道大家是否记得在上一小节中,当我们分析handleLaunchActivity()方法时,在第(3)点:当Activity被创建成功时,即a!=null,会去调用ActivityThread的handleResumeActivity()方法,该方法上述操作,具体如下:
 (1) 执行ActivityThread的performResumeActivity()方法,完成对Activity的onResume()调用。需要注意的是,当mStopped为true时,会先调用activity.onRestart();

public final ActivityClientRecord performResumeActivity(IBinder token,
        boolean clearHide) {
    ActivityClientRecord r = mActivities.get(token);
    ...
    // 调用activity.onResume()
    // 如果mStopped为ture,事先调用activity.onRestart()
    r.activity.performResume();
    ...
    return r;
}

 (2) 使用WindowManager将DecorView添加到Window中,完成Activity的视图到Window的绑定,其中,DecorView是Activity的顶层视图。关于WindowManager是如何addView的,请参考文章从Android 6.0源码的角度剖析Window内部机制原理

if (r.window == null && !a.mFinished && willBeVisible) {
      r.window = r.activity.getWindow();
      View decor = r.window.getDecorView();
      decor.setVisibility(View.INVISIBLE);
      ViewManager wm = a.getWindowManager();
      WindowManager.LayoutParams l = r.window.getAttributes();
      a.mDecor = decor;
      l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
      l.softInputMode |= forwardBit;
      if (a.mVisibleFromClient) {
          a.mWindowAdded = true;
          // 通过WindowManager将其添加到Window(窗体)中
          // 创建ViewRootImpl,发起View绘制流程,核心代码位于WindowManagerGlobal中
          wm.addView(decor, l);
      }
}

 (3) 调用Activity的makeVisible()方法使Activity得视图可见,即mDecor.setVisibility(View.VISIBLE)。至此,DecorView的添加和显示过程执行完毕。

if (r.activity.mVisibleFromClient) {
    r.activity.makeVisible();
}
//------------------------------------------------------------
void makeVisible() {
     if (!mWindowAdded) {
         ViewManager wm = getWindowManager();
         wm.addView(mDecor, getWindow().getAttributes());
         mWindowAdded = true;
     }
     mDecor.setVisibility(View.VISIBLE);
 }

 handResumeActivity源码如下:

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    // TODO Push resumeArgs into the activity for consideration
    // 执行onResume方法
    ActivityClientRecord r = performResumeActivity(token, clearHide);

    if (r != null) {
        final Activity a = r.activity;

        if (localLOGV) Slog.v(
            TAG, "Resume " + r + " started activity: " +
            a.mStartedActivity + ", hideForNow: " + r.hideForNow
            + ", finished: " + a.mFinished);

        final int forwardBit = isForward ?
                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

        // If the window hasn't yet been added to the window manager,
        // and this guy didn't finish itself or start another activity,
        // then go ahead and add the window.
        boolean willBeVisible = !a.mStartedActivity;
        if (!willBeVisible) {
            try {
                willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
                        a.getActivityToken());
            } catch (RemoteException e) {
            }
        }
        // 获取顶层视图DecorView
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                // 通过WindowManager将其添加到Window(窗体)中
                // 创建ViewRootImpl,发起View绘制流程,核心代码位于WindowManagerGlobal中
                wm.addView(decor, l);
            }

        // If the window has already been added, but during resume
        // we started another activity, then don't yet make the
        // window visible.
        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(
                TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }

        // Get rid of anything left hanging around.
        cleanUpPendingRemoveWindows(r);

        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            if (r.newConfig != null) {
                r.tmpConfig.setTo(r.newConfig);
                if (r.overrideConfig != null) {
                    r.tmpConfig.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                        + r.activityInfo.name + " with newConfig " + r.tmpConfig);
                // 调用onConfigurationChanged方法
                performConfigurationChanged(r.activity, r.tmpConfig);
                freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
                r.newConfig = null;
            }
            if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                    + isForward);
            WindowManager.LayoutParams l = r.window.getAttributes();
            if ((l.softInputMode
                    & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                    != forwardBit) {
                l.softInputMode = (l.softInputMode
                        & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                        | forwardBit;
                if (r.activity.mVisibleFromClient) {
                    ViewManager wm = a.getWindowManager();
                    View decor = r.window.getDecorView();
                    wm.updateViewLayout(decor, l);
                }
            }
            r.activity.mVisibleFromServer = true;
            mNumVisibleActivities++;

            // 显示DecorView,调用mDecor.setVisibity
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
        }

        if (!r.onlyLocalRequest) {
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            if (localLOGV) Slog.v(
                TAG, "Scheduling idle handler for " + r);
            Looper.myQueue().addIdleHandler(new Idler());
        }
        r.onlyLocalRequest = false;

        // Tell the activity manager we have resumed.
        if (reallyResume) {
            try {
                ActivityManagerNative.getDefault().activityResumed(token);
            } catch (RemoteException ex) {
            }
        }

    } else {
        // If an exception was thrown when trying to resume, then
        // just end this activity.
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(token, Activity.RESULT_CANCELED, null, false);
        } catch (RemoteException ex) {
        }
    }
}

猜你喜欢

转载自blog.csdn.net/AndrExpert/article/details/81488503