Activity配置android:multiprocess=“true“ 作用?

最近看腾讯开源的插件化框架shadow,发现宿主的Activity容器配置了

android:multiprocess="true" 这个属性有什么作用?
        <activity
            android:name="com.tencent.shadow.sample.plugin.runtime.PluginDefaultProxyActivity"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
            android:hardwareAccelerated="true"
            android:launchMode="standard"
            android:multiprocess="true"
            android:screenOrientation="portrait"
            android:theme="@style/troop_Transparent" />

让我们看一下系统源码:

系统在安装APK时会扫描解析AndroidManifest.解析组件,PackageParser.parseActivity 方法解析逻辑,得到一个标记位,保存在ActivityInfo的flags标记位里。如果android:multiprocess=true,那么对应标志位就置为1

        if (sa.getBoolean(
                R.styleable.AndroidManifestActivity_multiprocess, false)) {
            a.info.flags |= ActivityInfo.FLAG_MULTIPROCESS;
        }

Activity启动流程ActivityTaskManagerService.startActivity=>  ActivityTaskManagerService.startActivityAsUser

=>ActivityStarter.execute =>  ActivityStarter.executeRequest

此方法内部通过PMS的resolveIntent得到 ResolveInfo,进而得到安装扫描好的ActivityInfo

并传入ActivityInfo为新启动的Activity创建系统侧的ActivityRecord

        final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, callingFeatureId, intent, resolvedType, aInfo,
                mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
                request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
                sourceRecord);
        mLastStartActivityRecord = r;

ActivityRecord 构造函数关键代码,这里就是android:multiprocess=true的起作用地方了,

如果ActivityInfo的flag存在FLAG_MULTIPROCESS标记位,也是android:multiprocess=true,并且

调用进程存在,并且调用进程uid和组件的uid相同,那么这个activity就归属于调用进程。

反之则属于 android:process="xxxxx" 这个属性声明的进程,如果未声明则是默认使用包名为进程名。

    ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
            int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage,
            @Nullable String _launchedFromFeature, Intent _intent, String _resolvedType,
            ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo,
            String _resultWho, int _reqCode, boolean _componentSpecified,
            boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
            ActivityOptions options, ActivityRecord sourceRecord) {

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


        if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
                && (aInfo.applicationInfo.uid == SYSTEM_UID
                    || aInfo.applicationInfo.uid == _caller.mInfo.uid)) {
            processName = _caller.mName;
        } else {
            processName = aInfo.processName;
        }

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





   }

在创建ActvitiyRecord后,加入任务栈中,然后执行ActivityStack.resumeTopActivityInnerLocked

ActivityStack


private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (next.attachedToProcess()) {

            ...
            ...


        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwich */);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivity(next, true, true);
        }

ActivityStackSupervisor执行启动应用进程activity创建和生命周期逻辑,这里关键代码根据ActivityRecord的processName取到对应的进程WindowProcessController,其内部有IApplicationThread mThread,应用的binder,用于去执行应用端的相关组件操作。

ActivityStackSupervisor类中方法
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

综上:multiprocess 这个属性决定了ActivityRecord.processName的是那个,processName则对应了WindowProcessController里面的IApplicationThread是那个,这个IApplicationThread是一个binder,属于客户端应用进程发布给ActivityMangerService管理,用来远程操作应用进程执行组件的创建,生命周期回调。

总结:

1、Activity配置android:multiprocess="true" ,调用进程uid和组件的uid相同(一个应用的不同进程uid是相同的)则Activity跑在调用进程里面,调用进程是谁,他就跑在那个进程里,换句话说 Activity 可以跑在不同进程里面

2、Activity配置android:multiprocess="false" ,另外不配置也是false,则Activity跑在清单文件配置的进程里(android:process="xxxx"),如果没有指定process,则跑在应用包名进程也就是应用的主进程里,换句话说 Activity 只能跑在一个进程里,因为进程名限定死了,没配置进程名则是包名。

猜你喜欢

转载自blog.csdn.net/baidu_24392053/article/details/118275854