Inicio de la pantalla secundaria ActivityOptions

android12-release


1、Opciones de actividad

Clase auxiliar para crear Context.startActivity(Intent, Bundle)opciones que se pueden usar con métodos relacionados.
marcos/base/core/java/android/app/ActivityOptions.java

// 使用ActivityOptions指定显示屏幕
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(1); //这里display0是第一块屏;display1是第二块屏
Intent secondIntent = new Intent();
ComponentName cn= new ComponentName("com.android.demo""com.android.demo.SecondActivity");
secondIntent .setComponent(cn);
//该句很重要,不添加则无法推送到副屏,为Intent增加标志 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|Intent.FLAG_ACTIVITY_NEW_TASK
secondIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(secondIntent, options.toBundle());

Ver ActivityOptions#toBundle(): b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);que mLaunchDisplayIdes la pantalla de visualización de la configuración.

/**
 * Returns the created options as a Bundle, which can be passed to
 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
 * Context.startActivity(Intent, Bundle)} and related methods.
 * Note that the returned Bundle is still owned by the ActivityOptions
 * object; you must not modify it, but can supply it to the startActivity
 * methods that take an options Bundle.
 */
public Bundle toBundle() {
    
    
    Bundle b = new Bundle();
    if (mPackageName != null) {
    
    
        b.putString(KEY_PACKAGE_NAME, mPackageName);
    }
    if (mLaunchBounds != null) {
    
    
        b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds);
    }
    if (mAnimationType != ANIM_UNDEFINED) {
    
    
        b.putInt(KEY_ANIM_TYPE, mAnimationType);
    }
    if (mUsageTimeReport != null) {
    
    
        b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
    }
    switch (mAnimationType) {
    
    
        case ANIM_CUSTOM:
            b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
            b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
            b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                    != null ? mAnimationStartedListener.asBinder() : null);
            break;
        case ANIM_CUSTOM_IN_PLACE:
            b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
            break;
        case ANIM_SCALE_UP:
        case ANIM_CLIP_REVEAL:
            b.putInt(KEY_ANIM_START_X, mStartX);
            b.putInt(KEY_ANIM_START_Y, mStartY);
            b.putInt(KEY_ANIM_WIDTH, mWidth);
            b.putInt(KEY_ANIM_HEIGHT, mHeight);
            break;
        case ANIM_THUMBNAIL_SCALE_UP:
        case ANIM_THUMBNAIL_SCALE_DOWN:
        case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
        case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
            // Once we parcel the thumbnail for transfering over to the system, create a copy of
            // the bitmap to a hardware bitmap and pass through the HardwareBuffer
            if (mThumbnail != null) {
    
    
                final Bitmap hwBitmap = mThumbnail.copy(Config.HARDWARE, false /* isMutable */);
                if (hwBitmap != null) {
    
    
                    b.putParcelable(KEY_ANIM_THUMBNAIL, hwBitmap.getHardwareBuffer());
                } else {
    
    
                    Slog.w(TAG, "Failed to copy thumbnail");
                }
            }
            b.putInt(KEY_ANIM_START_X, mStartX);
            b.putInt(KEY_ANIM_START_Y, mStartY);
            b.putInt(KEY_ANIM_WIDTH, mWidth);
            b.putInt(KEY_ANIM_HEIGHT, mHeight);
            b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                    != null ? mAnimationStartedListener.asBinder() : null);
            break;
        case ANIM_SCENE_TRANSITION:
            if (mTransitionReceiver != null) {
    
    
                b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
            }
            b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
            b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
            b.putParcelable(KEY_RESULT_DATA, mResultData);
            b.putInt(KEY_RESULT_CODE, mResultCode);
            b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
            break;
    }
    if (mLockTaskMode) {
    
    
        b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode);
    }
    if (mLaunchDisplayId != INVALID_DISPLAY) {
    
    
        b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
    }
    if (mCallerDisplayId != INVALID_DISPLAY) {
    
    
        b.putInt(KEY_CALLER_DISPLAY_ID, mCallerDisplayId);
    }
    if (mLaunchTaskDisplayArea != null) {
    
    
        b.putParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, mLaunchTaskDisplayArea);
    }
    if (mLaunchRootTask != null) {
    
    
        b.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, mLaunchRootTask);
    }
    if (mLaunchWindowingMode != WINDOWING_MODE_UNDEFINED) {
    
    
        b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode);
    }
    if (mLaunchActivityType != ACTIVITY_TYPE_UNDEFINED) {
    
    
        b.putInt(KEY_LAUNCH_ACTIVITY_TYPE, mLaunchActivityType);
    }
    if (mLaunchTaskId != -1) {
    
    
        b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
    }
    if (mPendingIntentLaunchFlags != 0) {
    
    
        b.putInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, mPendingIntentLaunchFlags);
    }
    if (mTaskAlwaysOnTop) {
    
    
        b.putBoolean(KEY_TASK_ALWAYS_ON_TOP, mTaskAlwaysOnTop);
    }
    if (mTaskOverlay) {
    
    
        b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
    }
    if (mTaskOverlayCanResume) {
    
    
        b.putBoolean(KEY_TASK_OVERLAY_CAN_RESUME, mTaskOverlayCanResume);
    }
    if (mAvoidMoveToFront) {
    
    
        b.putBoolean(KEY_AVOID_MOVE_TO_FRONT, mAvoidMoveToFront);
    }
    if (mFreezeRecentTasksReordering) {
    
    
        b.putBoolean(KEY_FREEZE_RECENT_TASKS_REORDERING, mFreezeRecentTasksReordering);
    }
    if (mDisallowEnterPictureInPictureWhileLaunching) {
    
    
        b.putBoolean(KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING,
                mDisallowEnterPictureInPictureWhileLaunching);
    }
    if (mApplyActivityFlagsForBubbles) {
    
    
        b.putBoolean(KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, mApplyActivityFlagsForBubbles);
    }
    if (mAnimSpecs != null) {
    
    
        b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
    }
    if (mAnimationFinishedListener != null) {
    
    
        b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
    }
    if (mSpecsFuture != null) {
    
    
        b.putBinder(KEY_SPECS_FUTURE, mSpecsFuture.asBinder());
    }
    if (mSourceInfo != null) {
    
    
        b.putParcelable(KEY_SOURCE_INFO, mSourceInfo);
    }
    if (mRotationAnimationHint != -1) {
    
    
        b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
    }
    if (mAppVerificationBundle != null) {
    
    
        b.putBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE, mAppVerificationBundle);
    }
    if (mRemoteAnimationAdapter != null) {
    
    
        b.putParcelable(KEY_REMOTE_ANIMATION_ADAPTER, mRemoteAnimationAdapter);
    }
    if (mLaunchCookie != null) {
    
    
        b.putBinder(KEY_LAUNCH_COOKIE, mLaunchCookie);
    }
    if (mRemoteTransition != null) {
    
    
        b.putBinder(KEY_REMOTE_TRANSITION, mRemoteTransition.asBinder());
    }
    if (mOverrideTaskTransition) {
    
    
        b.putBoolean(KEY_OVERRIDE_TASK_TRANSITION, mOverrideTaskTransition);
    }
    if (mSplashScreenThemeResName != null && !mSplashScreenThemeResName.isEmpty()) {
    
    
        b.putString(KEY_SPLASH_SCREEN_THEME, mSplashScreenThemeResName);
    }
    if (mRemoveWithTaskOrganizer) {
    
    
        b.putBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER, mRemoveWithTaskOrganizer);
    }
    if (mLaunchedFromBubble) {
    
    
        b.putBoolean(KEY_LAUNCHED_FROM_BUBBLE, mLaunchedFromBubble);
    }
    if (mTransientLaunch) {
    
    
        b.putBoolean(KEY_TRANSIENT_LAUNCH, mTransientLaunch);
    }
    if (mSplashScreenStyle != 0) {
    
    
        b.putInt(KEY_SPLASH_SCREEN_STYLE, mSplashScreenStyle);
    }
    return b;
}

2. Convierta ActivityStarter en SafeActivityOptions

Ver el proceso de inicio de la aplicación AMS: aplicación de inicio de escritorio startActivity ; dónde ActivityStarter.java#setActivityOptions(bOptions)configurar

return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();

marcos/base/services/core/java/com/android/server/wm/ActivityStarter.java

ActivityStarter setActivityOptions(SafeActivityOptions options) {
    
    
    mRequest.activityOptions = options;
    return this;
}

ActivityStarter setActivityOptions(Bundle bOptions) {
    
    
    return setActivityOptions(SafeActivityOptions.fromBundle(bOptions));
}

marcos/base/services/core/java/com/android/server/wm/SafeActivityOptions.java

public static SafeActivityOptions fromBundle(Bundle bOptions) {
    
    
    return bOptions != null
            ? new SafeActivityOptions(ActivityOptions.fromBundle(bOptions))
            : null;
}

2.1 Solicitud.ActividadOpciones

marcos/base/services/core/java/com/android/server/wm/ActivityStarter.java

ActivityStarter setActivityOptions(SafeActivityOptions options) {
    
    
    mRequest.activityOptions = options;
    return this;
}

2.2 Opciones de ActivityRecord.m

marcos/base/services/core/java/com/android/server/wm/ActivityStarter.java

final ActivityRecord r = new ActivityRecord.Builder(mService)
        .setCaller(callerApp)
        .setLaunchedFromPid(callingPid)
        .setLaunchedFromUid(callingUid)
        .setLaunchedFromPackage(callingPackage)
        .setLaunchedFromFeature(callingFeatureId)
        .setIntent(intent)
        .setResolvedType(resolvedType)
        .setActivityInfo(aInfo)
        .setConfiguration(mService.getGlobalConfiguration())
        .setResultTo(resultRecord)
        .setResultWho(resultWho)
        .setRequestCode(requestCode)
        .setComponentSpecified(request.componentSpecified)
        .setRootVoiceInteraction(voiceSession != null)
        .setActivityOptions(checkedOptions)
        .setSourceRecord(sourceRecord)
        .build();

marcos/base/services/core/java/com/android/server/wm/ActivityRecord.java

Builder setActivityOptions(ActivityOptions options) {
    
    
    mOptions = options;
    return this;
}

2,3 mTargetRootTask

displayIdEncuentra el objetivo segúnDisplayContent、TaskDisplayArea、Task

marcos/base/services/core/java/com/android/server/wm/ActivityStarter.java

if (mTargetRootTask == null) {
    
    
    mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}

private Task getLaunchRootTask(ActivityRecord r, int launchFlags, Task task,
        ActivityOptions aOptions) {
    
    
    // We are reusing a task, keep the root task!
    if (mReuseTask != null) {
    
    
        return mReuseTask.getRootTask();
    }

    final boolean onTop =
            (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
    return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop,
            mLaunchParams, launchFlags, mRequest.realCallingPid, mRequest.realCallingUid);
}

marcos/base/services/core/java/com/android/server/wm/RootWindowContainer.java

/**
 * Returns the right root task to use for launching factoring in all the input parameters.
 *
 * @param r              The activity we are trying to launch. Can be null.
 * @param options        The activity options used to the launch. Can be null.
 * @param candidateTask  The possible task the activity might be launched in. Can be null.
 * @param sourceTask     The task requesting to start activity. Can be null.
 * @param launchParams   The resolved launch params to use.
 * @param launchFlags    The launch flags for this launch.
 * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
 * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
 * @return The root task to use for the launch or INVALID_TASK_ID.
 */
Task getLaunchRootTask(@Nullable ActivityRecord r,
        @Nullable ActivityOptions options, @Nullable Task candidateTask,
        @Nullable Task sourceTask, boolean onTop,
        @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags,
        int realCallingPid, int realCallingUid) {
    
    
    int taskId = INVALID_TASK_ID;
    int displayId = INVALID_DISPLAY;
    TaskDisplayArea taskDisplayArea = null;

    // We give preference to the launch preference in activity options.
    if (options != null) {
    
    
        taskId = options.getLaunchTaskId();
        displayId = options.getLaunchDisplayId();
        final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
        taskDisplayArea = daToken != null
                ? (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder()) : null;

        final Task rootTask = Task.fromWindowContainerToken(options.getLaunchRootTask());
        if (rootTask != null) {
    
    
            return rootTask;
        }
    }

    // First preference for root task goes to the task Id set in the activity options. Use
    // the root task associated with that if possible.
    if (taskId != INVALID_TASK_ID) {
    
    
        // Temporarily set the task id to invalid in case in re-entry.
        options.setLaunchTaskId(INVALID_TASK_ID);
        final Task task = anyTaskForId(taskId,
                MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE, options, onTop);
        options.setLaunchTaskId(taskId);
        if (task != null) {
    
    
            return task.getRootTask();
        }
    }

    final int activityType = resolveActivityType(r, options, candidateTask);
    Task rootTask = null;

    // Next preference for root task goes to the taskDisplayArea candidate.
    if (launchParams != null && launchParams.mPreferredTaskDisplayArea != null) {
    
    
        taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
    }

    if (taskDisplayArea == null && displayId != INVALID_DISPLAY) {
    
    
        final DisplayContent displayContent = getDisplayContent(displayId);
        if (displayContent != null) {
    
    
            taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
        }
    }

    if (taskDisplayArea != null) {
    
    
        final int tdaDisplayId = taskDisplayArea.getDisplayId();
        final boolean canLaunchOnDisplayFromStartRequest =
                realCallingPid != 0 && realCallingUid > 0 && r != null
                        && mTaskSupervisor.canPlaceEntityOnDisplay(tdaDisplayId,
                        realCallingPid, realCallingUid, r.info);
        if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) {
    
    
            if (r != null) {
    
    
                final Task result = getValidLaunchRootTaskInTaskDisplayArea(
                        taskDisplayArea, r, candidateTask, options, launchParams);
                if (result != null) {
    
    
                    return result;
                }
            }
            // Falling back to default task container
            taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea();
            rootTask = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
                    sourceTask, launchParams, launchFlags, activityType, onTop);
            if (rootTask != null) {
    
    
                return rootTask;
            }
        }
    }

    // Give preference to the root task and display of the input task and activity if they
    // match the mode we want to launch into.
    TaskDisplayArea container = null;
    if (candidateTask != null) {
    
    
        rootTask = candidateTask.getRootTask();
    }
    if (rootTask == null && r != null) {
    
    
        rootTask = r.getRootTask();
    }
    int windowingMode = launchParams != null ? launchParams.mWindowingMode
            : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
    if (rootTask != null) {
    
    
        container = rootTask.getDisplayArea();
        if (container != null && canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
    
    
            if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
    
    
                windowingMode = container.resolveWindowingMode(r, options, candidateTask,
                        activityType);
            }
            // Always allow organized tasks that created by organizer since the activity type
            // of an organized task is decided by the activity type of its top child, which
            // could be incompatible with the given windowing mode and activity type.
            if (rootTask.isCompatible(windowingMode, activityType)
                    || rootTask.mCreatedByOrganizer) {
    
    
                return rootTask;
            }
        }
    }

    if (container == null
            || !canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
    
    
        container = getDefaultTaskDisplayArea();
        if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
    
    
            windowingMode = container.resolveWindowingMode(r, options, candidateTask,
                    activityType);
        }
    }

    return container.getOrCreateRootTask(r, options, candidateTask, sourceTask, launchParams,
            launchFlags, activityType, onTop);
}

3. Contexto relacionado con la aplicación

3.1 Aplicación中Contexto

Se crea la aplicación ActivityThread.java#handleBindApplication -> LoadedApk.java#makeApplication; por lo tanto Application中Context, no ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);hay DispalyIdconfiguraciones en ella.

marcos/base/core/java/android/app/LoadedApk.java

public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    
    
    if (mApplication != null) {
    
    
        return mApplication;
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
    
    
        appClass = "android.app.Application";
    }

    try {
    
    
        final java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
    
    
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    "initializeJavaContextClassLoader");
            initializeJavaContextClassLoader();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }

        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(
                false, false);
        for (int i = 0, n = packageIdentifiers.size(); i < n; i++) {
    
    
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
    
    
                continue;
            }

            rewriteRValues(cl, packageIdentifiers.valueAt(i), id);
        }

        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        // The network security config needs to be aware of multiple
        // applications in the same process to handle discrepancies
        NetworkSecurityConfigProvider.handleNewApplication(appContext);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
    
    
        if (!mActivityThread.mInstrumentation.onException(app, e)) {
    
    
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            throw new RuntimeException(
                "Unable to instantiate application " + appClass
                + " package " + mPackageName + ": " + e.toString(), e);
        }
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    if (instrumentation != null) {
    
    
        try {
    
    
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
    
    
            if (!instrumentation.onException(app, e)) {
    
    
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to create application " + app.getClass().getName()
                    + ": " + e.toString(), e);
            }
        }
    }

    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    return app;
}

marcos/base/core/java/android/app/Instrumentation.java

public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    
    
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

3.2 Contexto durante la actividad

Activity中ContextEn activity.attach()la configuración, entonces Application中Contextpara ContextImpl appContext = createBaseContextForActivity(r);, es decir, en ContextImpl.createActivityContext()la configuraciónDispalyId

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
    
    
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

    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);
    }

    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
    
    
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                appContext.getAttributionSource());
        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 {
    
    
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());

        if (activity != null) {
    
    
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config =
                    new Configuration(mConfigurationController.getCompatConfiguration());
            if (r.overrideConfig != null) {
    
    
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
    
    
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }

            // Activity resources must be initialized with the same loaders as the
            // application context.
            appContext.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

            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,
                    r.assistToken, r.shareableActivityToken);

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

            if (r.mActivityOptions != null) {
    
    
                activity.mPendingOptions = r.mActivityOptions;
                r.mActivityOptions = null;
            }
            activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
            activity.mCalled = false;
            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;
            mLastReportedWindowingMode.put(activity.getActivityToken(),
                    config.windowConfiguration.getWindowingMode());
        }
        r.setState(ON_CREATE);

        // updatePendingActivityConfiguration() reads from mActivities to update
        // ActivityClientRecord which runs in a different thread. Protect modifications to
        // mActivities to avoid race.
        synchronized (mResourcesManager) {
    
    
            mActivities.put(r.token, r);
        }

    } catch (SuperNotCalledException e) {
    
    
        throw e;

    } catch (Exception e) {
    
    
        if (!mInstrumentation.onException(activity, e)) {
    
    
            throw new RuntimeException(
                "Unable to start activity " + component
                + ": " + e.toString(), e);
        }
    }

    return activity;
}
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
    
    
    final int displayId = ActivityClient.getInstance().getDisplayId(r.token);
    ContextImpl appContext = ContextImpl.createActivityContext(
            this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);

    // The rotation adjustments must be applied before creating the activity, so the activity
    // can get the adjusted display info during creation.
    if (r.mPendingFixedRotationAdjustments != null) {
    
    
        // The adjustments should have been set by handleLaunchActivity, so the last one is the
        // override for activity resources.
        if (mActiveRotationAdjustments != null && !mActiveRotationAdjustments.isEmpty()) {
    
    
            mResourcesManager.overrideTokenDisplayAdjustments(r.token,
                    mActiveRotationAdjustments.get(
                            mActiveRotationAdjustments.size() - 1).second);
        }
        r.mPendingFixedRotationAdjustments = null;
    }

    final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
    // For debugging purposes, if the activity's package name contains the value of
    // the "debug.use-second-display" system property as a substring, then show
    // its content on a secondary display if there is one.
    String pkgName = SystemProperties.get("debug.second-display.pkg");
    if (pkgName != null && !pkgName.isEmpty()
            && r.packageInfo.mPackageName.contains(pkgName)) {
    
    
        for (int id : dm.getDisplayIds()) {
    
    
            if (id != Display.DEFAULT_DISPLAY) {
    
    
                Display display =
                        dm.getCompatibleDisplay(id, appContext.getResources());
                appContext = (ContextImpl) appContext.createDisplayContext(display);
                break;
            }
        }
    }
    return appContext;
}

Supongo que te gusta

Origin blog.csdn.net/qq_23452385/article/details/132126884
Recomendado
Clasificación