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

一个月左右写了图像显示深入学习之文章开篇文章表明了自己近期的计划,前半年重新学习了opengl es,c++以及Linux的一些知识,觉得是时候开始看图像这一块的源码了,边看边补缺补漏吧。

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

文章基于8.0源码研究分析

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

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

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

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

实现源码如下所示:

//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对象,这个暂时推断不出作用,先暂时留着。

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中具体代码实现如下:

 //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进行处理。

由应用进程通知到对应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。

转载于:https://my.oschina.net/u/3863980/blog/2207982

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值