图像显示深刻学习一:Activity启动过程

一个月左右写了图像显示深刻学习之文章开篇文章代表了本身近期的计划,前半年从新学习了opengl es,c++以及Linux的一些知识,以为是时候开始看图像这一块的源码了,边看边补缺补漏吧。java

做为该系列文章的第一篇开篇,总以为仍是应该从Activity开始提及,毕竟图像模块跟Activity是分不开的。刚毕业时候也写过Activity对应的文章,结果忘了放哪了,这里就从新梳理一遍,加深记忆吧。ios

文章基于8.0源码研究分析c++

文章思路基于三个方面依次进行研究学习:安全

  • startActivity()在应用进程中
  • 由应用进程通知到对应ActivityManagerService(下面简称AMS)后在AMS中的实现的源码流程
  • 从AMS返回到应用进程中的调用过程

startActivity()在应用进程中的源码走读

从最开始接触Acvtivity类从startActivity(...)开始,那么直接从这个方法若是追溯一下Activity启动的运做过程。startActivity(...)的实现类在ContextWrapper中,由Activity继承ContextThemeWrapper进行重写,关于Context的总结图(图片来自郭霖巨巨)以下:网络

实现源码以下所示:app

//Activity.java
...
 @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }
...
 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);
          ....
        } 
...

方法内部调用mInstrumentation.execStartActivity()进行进一步处理。mMainThread是ActivityThread类的实例,一个应用程序对应着一个ActivityThread,ActvityThread能够当作应用程序主线程理解。ApplicationThread为ActivityThread的内部类,其继承自IApplicationThread.Stub,是一个Binder对象,从Stub关键字就能够推断出,一个ActivityThread都有一个ApplicationThread,主要负责跟其它进程进行通讯。mToken来自于ActivityClientRecord.token变量,表明一个Binder对象,这个暂时推断不出做用,先暂时留着。ide

mInstrumentation为Instrumentation类实例,Instrumentation类用于监控应用程序和系统的交互(在Mainfest文件中,咱们能够声明Instrumentation节点来作一些事)。execStartActivity(...)方法以下:学习

//Instrumentation.java
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
       ....
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
			//whoThread为ActivityThread中的ApplcaitionThread
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

方法中调用ActivityManager.getService()得到一个IActivityManager,IActivityManager自己是一个aidl文件,文件路径在/frameworks/base/core/app目录下。ActivityManager中具体代码实现以下:ui

//ActivityManager.java
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

IActivityManager的实现类由ActivityManagerService担任,在AMS源码中能够看到其继承了IActivityManager.Stub。AMS与应用程序在不一样的进程内,因此使用了Binder机制进行通讯。到此为止,startActivity()在应用进程中的源码走读就已经完成了,接下来的工做交付给了AMS进行处理。this

由应用进程通知到对应ActivityManagerService(下面简称AMS)后在AMS中的实现的源码流程

在AMS中的startActivity(...)实现以下:

//AMS.java
@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,
                "startActivityAsUser");
    }

这里调到了mActivityStarter.startActivityMayWait(...)中,ActivityStarter在AMS初始化时一同被初始化,其掌管着AMS内部处理Activity的start的逻辑。在研究以前先整理一下PackageInfo,ActivityInfo,ResolveInfo等的意义。

  • PackageInfo:标识apk信息,能够理解为系统解析了Manifest.xml后保存信息的地方。
  • ApplicationInfo:保存Appllication节点信息。
  • ActivityInfo(ServiceInfo,RecevierInfo...):保存一个Manifest.xml中Activity(Service,Receiver...)节点的信息。
  • ResolveInfo:保存系统解析对应Intent的信息。

PackageInfo中包含的ActivityInfos,ServicesInfos,ApplicationInfo等信息,通常咱们经过PackManager能够获取到PackageInfo。

下面继续查看mActivityStarter.startActivityMayWait(...),具体方法以下:

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {
        ...
		//步骤1.解析获取当前的ResolveInfo
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
        ...
       //步骤2.获取要启动的Activity的信息
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
		//传入的iContainer为null
        ActivityStackSupervisor.ActivityContainer container =
                (ActivityStackSupervisor.ActivityContainer)iContainer;
			...
            final ActivityRecord[] outRecord = new ActivityRecord[1];
			//步骤3
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask, reason);

          ...
            return res;
        }
    }

这一块的代码比较复杂,但也是核心的代码,直接挑选重要的代码片断分析,较为无关的这里就略过了。

首先看步骤1,能够了解的是该步骤的做用是为了获取一个ResolveIntent,调用mSupervisor.resolveIntent(...)的方法内部会经过mService.getPackageManagerInternalLocked()调用LocalService获取PackageManagerInternal实现类PackageManagerInternal(该类实如今PackageManagerService内部),继而调用其resolveIntent(...),最终解析得到ResolveIntent,关于内部的逻辑不深究进去,日后若是深刻再继续研究便可。

步骤2获取对应启动的Activitynfo,在获取ResolveInfo阶段,其实就把对应的Activitynfo解析获取到了,mSupervisor.resolveIntent(...)会根据ResolveInfo获取Activitynfo。

步骤3调用startActivityLock(....)方法,该方法内会进而调用startActivity(...)方法,在startActivity(...)中会进行一些校验性的工做,如目标Activity的合法性,Activity是否须要对应权限等等,而且还会为原来的Activity生成一个ActivityRecord对象记录对应信息,传递给下一层startActivity(...)方法(这里有两个startActivity方法,不是笔误),第二个startActivity(...)中调用startActivityUnchecked(...):

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
		//从新计算纠正mLaunchFlags,即LauchMode
        computeLaunchingTaskFlags();
		//context.satrtActivityForResult(...)会用到,这里不介绍
        computeSourceStack();
		
        mIntent.setFlags(mLaunchFlags);
		//获取重用的ActivityRecord,主要在于咱们设置了NEW_TASK的IntentFlag的重用,能够想一想singleTask的LaunchMode就能理解
        ActivityRecord reusedActivity = getReusableIntentActivity();
		//因为咱们分析的场景在标准的LaunchMode下,因此忽略reusedActivity的处理
        ...
		//mStartActivity赋值为了r
		...
		//singleTop下的处理忽略
        final ActivityStack topStack = mSupervisor.mFocusedStack;
        final ActivityRecord topFocused = topStack.topActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        ...

        boolean newTask = false;
        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTask() : null;

        // Should this be considered a new task?
        int result = START_SUCCESS;
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            setTaskToCurrentTopOrCreateNewTask();
        }
        if (result != START_SUCCESS) {
            return result;
        }

       ...
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
		//mDoResume为真
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
          ....
            } else {
                // If the target stack was not previously focusable (previous top running activity
                // on that stack was not visible) then any prior calls to move the stack to the
                // will not update the focused stack.  If starting the new activity now allows the
                // task stack to be focusable, then ensure that we now update the focused stack
                // accordingly.
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
      ...
        return START_SUCCESS;
    }

上面仍是进行了一系列验证工做而后调用到了 mSupervisor.resumeFocusedStackTopActivityLocked(...)中:

boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
	mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
...
	result = resumeTopActivityInnerLocked(prev, options);
...
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
	mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
}
//ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
	    
...
	realStartActivityLocked(r, app, andResume, checkConfig);
...
}

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
...
	//r.appToken是一个window manager token
	app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global and
                    // override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
...
}

通过一系列的调用,最终调用到了ActivityStackSuperviosr中的realStartActivityLocked(...)方法中,在方法内调用了app.thread.scheduleLaunchActivity(....)方法,在跟踪代码的过程当中会遇到关键几个类,这里总结一下:

  • ActivityStackSupervisor:ActivityStackSupervisor充当管理ActivityStack的角色
  • ActivityStack:ActivityStack则是用来管理TaskRecord的,包含了多个TaskRecord。一个app中可能会有多个Task,对应在源码中就是多个TaskRecord。
  • TaskRecord:一个TaskRecord由一个或者多个ActivityRecord组成,开发中咱们称为任务栈(后进先出)的实现。
  • ActivityReorcd:Activity在ActivitySatck中的一个entry,表明着entry保存的Activity的信息。每个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord。

总结一张图(图片来自网络,侵删)以下:

图片来自网络,侵删

继续分下,上面的app为ProcessRecord,记录中一个活动进程中的全部信息,app中的thread参数为IApplicationThread,对应着ApplicationThread,也就是咱们一开始分析过的类,这里回调scheduleLaunchActivity(...)方法,即回调到客户端进程中。

到这里,由应用进程通知到对应ActivityManagerService后在AMS中的实现的源码流程就串联完毕了。对应的UML图走一波:

从AMS返回到应用进程中的调用过程

从第二阶段的分析后,咱们知道回调到了应用进程中的ApplicationThread.scheduleLaunchActivity(...)方法:

// we use token to identify this activity without having to send the
        // activity itself back to the activity manager. (matters more with ipc)
        @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
            ActivityClientRecord r = new ActivityClientRecord();
			//由AMS进程传来的window manager token,这里能够解决上面提出的疑问了
            r.token = token;
          	...
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

最终调到mH实例中,mH是一个Handler实现类,那么这里就知道回到了主线程当中,代码实现以下:

public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                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, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
				....
}

再次调到了handleLaunchActivity(...):

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
       ...
        //这个到时候研究图像一块会用到
        WindowManagerGlobal.initialize();
		//步骤1
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
           ...
			//步骤2
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
			...
    }

这段代码中主要分两个步骤进行:

步骤1中调用performLaunchActivity (...)对新启动的Activity作初始化,主要代码以下:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		...
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
           ...
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
			...
            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
               ...
                appContext.setOuterContext(activity);
                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, r.configCallback);
               ...
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
               ...
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                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);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    ...
        return activity;
    }

该方法中主要涵盖以下几个初始化的过程:

  • 设置来自源Activity的Intent到启动的Activity上。
  • 调用ClassLoader反射实例化目标Activity。
  • 调用activity.attach(...)方法设置Activity的内部变量。
  • 设置Activity主题。
  • 调用目标Activity的onCreate(...)onStart(...),onRestoreInstanceState(...)onPostCreate(...)

这里主要看activity.attach(...)方法吧:

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,
            Window window, ActivityConfigCallback activityConfigCallback) {
      	...
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
		...
        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());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;

        mWindow.setColorMode(info.colorMode);
    }

主要的就是PhoneWindow在Activity调用attach(...)方法进行了初始化的工做,接来的文章须要用到该模块的知识,因此在此记录一下。

步骤2中调用handleResumeActivity (...):

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ActivityClientRecord r = mActivities.get(token);
       	...
        // TODO Push resumeArgs into the activity for consideration
        r = performResumeActivity(token, clearHide, reason);

        if (r != null) {
            final Activity a = r.activity;
			...
            final int forwardBit = isForward ?
                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

           	//Activity中的mStartedActivity表明是requestCode是否大于0,在咱们分析的情境下为false,那么willBeVisible=true
            boolean willBeVisible = !a.mStartedActivity;
           ...
			//此时的r.window为null
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();//PhoneWindow
                View decor = r.window.getDecorView();//获取DecorView
                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;
               ...
			   //mVisibleFromClient描述一个应用程序窗口是不是可见的
                if (a.mVisibleFromClient) {
                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
						//添加DecorView到window中
                        wm.addView(decor, l);
                    } else {
                      
                        a.onWindowAttributesChanged(l);
                    }
                }

            ...
            if (!r.activity.mFinished && willBeVisible
                    && r.activity.mDecor != null && !r.hideForNow) {
               ...
                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);
                    }
                }	
				//设置可见
                if (r.activity.mVisibleFromClient) {
                    r.activity.makeVisible();
                }
            }
			...
    }

这里作两件事情,第一件为回调activity.onResume(...)方法,第二件是主要是对视图进行更新的操做,涉及的类为WindowManger,下面的章节介绍,这里不细说。activity.onResume(...)调用的位置在performResumeActivity(...)中:

public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        ...
                r.activity.performResume();

                synchronized (mResourcesManager) {
                    for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
                        final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
                        if (relaunching.token == r.token
                                && relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
                            relaunching.startsNotResumed = false;
                        }
                    }
                }

              ...
        return r;
    }

到此为止,从Context.startActvity(...)的调用到Activity.onResume(..)的过程就已经分析完毕了。


总结

上述的分析大致清理了一下Context.startActvity(...)的调用到Activity.onResume(..)的脉络,涉及的知识点也不少,其中包括Binder机制,Activity的四大启动模式(LaunchMode),PackageRecord,ResolveInfo等等存储的信息以及Handler机制的运用等等等,相较于之前写的文章,整体上的理解也更加深入了一些,证实本身的努力没有白费吧,技术的路上仍是要RTFC。

相关文章
相关标签/搜索