文档章节

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

JerryLin123
 JerryLin123
发布于 2018/09/23 21:23
字数 3399
阅读 64
收藏 3

一个月左右写了图像显示深入学习之文章开篇文章表明了自己近期的计划,前半年重新学习了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。

© 著作权归作者所有

JerryLin123
粉丝 9
博文 67
码字总数 147047
作品 0
东城
私信 提问
Android深入四大组件(七)Android8.0 根Activity启动过程(后篇)

相关文章 Android深入四大组件系列 Android系统启动系列 Android应用程序进程系列 Android深入解析AMS系列 前言 在几个月前我写了Android深入四大组件(一)应用程序启动过程(前篇)和Andro...

刘望舒
2017/12/25
0
0
Android深入四大组件(六)Android8.0 根Activity启动过程(前篇)

相关文章 Android深入四大组件系列 Android系统启动系列 Android应用程序进程系列 Android深入解析AMS系列 前言 在几个月前我写了Android深入四大组件(一)应用程序启动过程(前篇)和Andro...

刘望舒
2017/11/27
0
0
Android framework——Activity的启动和创建

本人制作的app:1号密码 欢迎试用   最近学习Android相关知识,感觉仅仅了解Activity几个生命周期函数基本上没有任何意义的; 于是想深入了解一下Activity到底是怎么一回事怎么运行来的;里...

jackxu2015
2015/08/14
172
0
图像显示深入学习三:窗口机制分析

上一篇文章图像显示深入学习一:Activity启动过程中介绍了启动一个Activity在整个Android系统中执行的流程,其中可以看到Window的创建,这篇文章就整理一下Window机制的实现过程吧。 吐个槽,...

JerryLin123
2018/10/14
19
0
Android AOSP基础(一)趁周末用VirtualBox 安装 Ubuntu吧

本文首发于微信公众号「刘望舒」 相关系列文章 Android系统启动系列 应用进程启动系列 Android深入四大组件系列 Android深入理解Context系列 Android深入理解JNI系列 Android解析WindowManag...

刘望舒
05/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

聊聊nacos的LocalConfigInfoProcessor

序 本文主要研究一下nacos的LocalConfigInfoProcessor LocalConfigInfoProcessor nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java p......

go4it
昨天
4
0
前端技术之:webpack热模块替换(HMR)

第一步:安装HMR中间件: npm install --save-dev webpack-hot-middleware 第二步:webpack配置中引入webpack对象 const webpack = require('webpack’); 第三步:增加devServer配置项: ho......

popgis
昨天
4
0
死磕 java线程系列之线程池深入解析——体系结构

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 Java的线程池是块硬骨头,对线程池的源码做深入研究不仅能提高对Java整个并发编程的理解,也能提高自己...

彤哥读源码
昨天
4
0
虚函数表 图解

虚函数表 图解 p504

天王盖地虎626
昨天
3
0
java反射

学习目标  什么是反射  反射运行原理  了解反射机制的相关类  获取 class 对象的 3 种方式  通过反射获取构造方法并使用  通过反射获取成员变量并调用  通过反射获取成员方法并...

流川偑
昨天
4
2

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部