Android 12系统源码_窗口动画(一) ActivityOptions实现窗口打开动画的流程

一、通过ActivityOptions获取Activity对应的打开动画

1、我们可以通过ActivityOptions类,实现打开Activity的时候有对应的缩放动画。

    private void startActivity(View view) {
        int width = view.getMeasuredWidth();
        int height = view.getMeasuredHeight();
        Log.d(TAG, "startActivity: witch = " + width + " height = " + height);
        //打开Activity的时候添加从View逐渐缩放到全屏的Activity打开动画
        ActivityOptions activityOptions = ActivityOptions.makeScaleUpAnimation(view, 0, 0, width, height);
        Intent intent = new Intent();
        startActivity(intent, activityOptions.toBundle());
    }

以上代码主要是调用ActivityOptions的makeScaleUpAnimation方法,为Activity添加打开动画的。

2、通过ActivityOptions我们可以获取到很多种Activity的打开动画。

base/core/java/android/app/ActivityOptions.java

public class ActivityOptions {

	//缩放动画
    public static ActivityOptions makeScaleUpAnimation(View source,
            int startX, int startY, int width, int height) {
        ActivityOptions opts = new ActivityOptions();
        opts.mPackageName = source.getContext().getPackageName();
        opts.mAnimationType = ANIM_SCALE_UP;
        int[] pts = new int[2];
        source.getLocationOnScreen(pts);
        opts.mStartX = pts[0] + startX;
        opts.mStartY = pts[1] + startY;
        opts.mWidth = width;
        opts.mHeight = height;
        return opts;
    }

	//裁剪动画
    public static ActivityOptions makeClipRevealAnimation(View source,
            int startX, int startY, int width, int height) {
        ActivityOptions opts = new ActivityOptions();
        opts.mAnimationType = ANIM_CLIP_REVEAL;
        int[] pts = new int[2];
        source.getLocationOnScreen(pts);
        opts.mStartX = pts[0] + startX;
        opts.mStartY = pts[1] + startY;
        opts.mWidth = width;
        opts.mHeight = height;
        return opts;
    }
    
    //自定义动画
    public static ActivityOptions makeCustomAnimation(Context context,
            int enterResId, int exitResId) {
        return makeCustomAnimation(context, enterResId, exitResId, null, null, null);
    }

    //自定义动画    
    public static ActivityOptions makeCustomAnimation(Context context,
            int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) {
        ActivityOptions opts = new ActivityOptions();
        opts.mPackageName = context.getPackageName();
        opts.mAnimationType = ANIM_CUSTOM;
        opts.mCustomEnterResId = enterResId;
        opts.mCustomExitResId = exitResId;
        opts.setOnAnimationStartedListener(handler, listener);
        return opts;
    }

	//场景过渡动画
    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
            Pair<View, String>... sharedElements) {
        ActivityOptions opts = new ActivityOptions();
        ExitTransitionCoordinator exit = makeSceneTransitionAnimation(
                new ActivityExitTransitionCallbacks(activity), activity.mExitTransitionListener,
                activity.getWindow(), opts, sharedElements);
        opts.mExitCoordinatorIndex =
                activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
        return opts;
    }

	//缩略图缩放动画
    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
            Bitmap thumbnail, int startX, int startY) {
        return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null);
    }

	//缩略图缩放动画
    private static ActivityOptions makeThumbnailScaleUpAnimation(View source,
            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
        return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
    }

	//缩略图缩放动画
    private static ActivityOptions makeThumbnailAnimation(View source,
            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
            boolean scaleUp) {
        ActivityOptions opts = new ActivityOptions();
        opts.mPackageName = source.getContext().getPackageName();
        opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;
        opts.mThumbnail = thumbnail;
        int[] pts = new int[2];
        source.getLocationOnScreen(pts);
        opts.mStartX = pts[0] + startX;
        opts.mStartY = pts[1] + startY;
        opts.setOnAnimationStartedListener(source.getHandler(), listener);
        return opts;
    }
 }
  • makeScaleUpAnimation(View source, int startX, int startY, int startWidth, int startHeight): 创建缩放动画,使目标 Activity 从指定的起始位置和大小缩放到其正常大小。可以指定动画起始位置和大小。

  • makeClipRevealAnimation(View source, int startX, int startY, int startWidth, int startHeight): 创建裁剪揭示动画,使目标 Activity 从指定的起始位置开始逐渐揭示出来。可以指定动画起始位置和大小。

  • makeCustomAnimation(int enterResId, int exitResId): 创建自定义的 Activity 进入和退出动画。通过传入进入动画资源 ID 和退出动画资源 ID 来定义自定义的动画效果。

  • makeSceneTransitionAnimation(Activity activity, Pair<View, String>… sharedElements): 创建场景过渡动画,用于在两个 Activity 之间共享元素的平滑过渡。可以传入一个或多个共享元素及其对应的名称。

  • makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY): 创建缩略图缩放动画,使目标 Activity 从指定的缩略图位置开始放大。可以指定缩略图和动画起始位置。

3、由于startActivity方法使用的是Bundle参数,ActivityOptions提供了toBundle方法,可以将自己转化成对应的参数类型。

public class ActivityOptions {

    public static final String KEY_ANIM_TYPE = "android:activity.animType";
    public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
    public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
    public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
    public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
    public static final String KEY_ANIM_START_X = "android:activity.animStartX";
    public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
    public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
    public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
    public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
    public static final String KEY_SPLASH_SCREEN_THEME = "android.activity.splashScreenTheme";
    private static final String KEY_ANIMATION_FINISHED_LISTENER ="android:activity.animationFinishedListener";
    private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
    
    private int mAnimationType = ANIM_UNDEFINED;//动画类型,默认为未定义

    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://自定义动画,允许启动和结束的Activity定义不同的动画
                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://这种动画效果会在启动新的 Activity 时,使用一个全屏的界面缩略图,并将其缩小为新界面。用户会看到全屏界面逐渐缩小到新界面的大小,这种效果通常用于突出原始界面的退出,使界面过渡更加平滑和自然
            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 (mLaunchTaskFragmentToken != null) {
            b.putBinder(KEY_LAUNCH_TASK_FRAGMENT_TOKEN, mLaunchTaskFragmentToken);
        }
        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.putParcelable(KEY_REMOTE_TRANSITION, mRemoteTransition);
        }
        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;
    }
}

二、ActivityThread和Activity生命周期相关的源码调用

1、ActivityThread主要是在Handler的handleMessage方法中,触发Activity的生命回调的。

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    
    final H mH = new H();//消息Handler
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);//管理Activity生命周期的回调
    
    class H extends Handler {
        public static final int EXECUTE_TRANSACTION = 159;

        public void handleMessage(Message msg) {
            switch (msg.what) {
 				...代码省略...
                case EXECUTE_TRANSACTION://触发Activity生命周期回调的关键消息事件
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    break;
 				...代码省略...
            }
        }
    }
}

handleMessage方法主要是通过TransactionExecutor的execute方法触发Activity生命周期回调的。

2、TransactionExecutor的execute方法如下所示。

base/core/java/android/app/servertransaction/TransactionExecutor.java

public class TransactionExecutor {

    private ClientTransactionHandler mTransactionHandler;
    
    public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
        mTransactionHandler = clientTransactionHandler;//这里的clientTransactionHandler就是ActivityThread对象
    }
    
    public void execute(ClientTransaction transaction) {
    	...代码省略...
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
    	...代码省略...
    }
    
    private void executeLifecycleState(ClientTransaction transaction) {
    	...代码省略...
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
    	...代码省略...
    }

    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path, transaction);
    }

    private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            switch (state) {
                case ON_CREATE: //触发ActivityThread的handleLaunchActivity方法
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START: //触发ActivityThread的handleLaunchActivity方法
                    mTransactionHandler.handleStartActivity(r, mPendingActions,
                            null /* activityOptions */);
                    break;
                case ON_RESUME: //触发ActivityThread的handleResumeActivity方法
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE: //触发ActivityThread的handlePauseActivity方法
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP: //触发ActivityThread的handleStopActivity方法
                    mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
                            mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY: //触发ActivityThread的handleDestroyActivity方法
                    mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART: //触发ActivityThread的performRestartActivity方法
                    mTransactionHandler.performRestartActivity(r, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }
}

TransactionExecutor的execute方法最终会触发ActivityThread和Activity生命周期回调相关的方法。

3、来看下ActivityThread和Activity生命周期回调相关的方法。

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    
    Instrumentation mInstrumentation;
    
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ...代码省略...
        //继续调用performLaunchActivity方法
        final Activity a = performLaunchActivity(r, customIntent);
        ...代码省略...
    }

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
         ...代码省略...
         //通过反射创建Activity实例对象
  		 Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
         ...代码省略...
         //触发Activity的attach方法,此方法是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);
         ...代码省略...
         //调用Instrumentation的callActivityOnCreate方法,该方法最终会触发Activity的onCreate方法                        
         if (r.isPersistable()) {
             mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
         } else {
             mInstrumentation.callActivityOnCreate(activity, r.state);
         }
         ...代码省略...
    }
    
    @Override
    public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
        final Activity activity = r.activity;
         ...代码省略...
        //调用Activity的performStart方法
        activity.performStart("handleStartActivity");
        ...代码省略...
    }

    @Override
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, String reason) {
      	...代码省略...
      	//调用performResumeActivity方法
        if (!performResumeActivity(r, finalStateRequest, reason)) {
            return;
        }
        ...代码省略...
        r.window = r.activity.getWindow();
        View decor = r.window.getDecorView();
         //添加窗口,在这之后,Actiivty对应的视图才开始可见
         wm.addView(decor, l);
        ...代码省略...
    }

    public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            String reason) {
        ...代码省略...
        //调用Activity的performResume方法
        r.activity.performResume(r.startsNotResumed, reason);
        ...代码省略...
    }

    @Override
    public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason) {
        ...代码省略...
        //继续调用performPauseActivity方法
        performPauseActivity(r, finished, reason, pendingActions);
        ...代码省略...
    }
    
    private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
            PendingTransactionActions pendingActions) {
        ...代码省略...
        //继续调用performPauseActivityIfNeeded方法
        performPauseActivityIfNeeded(r, reason);
        ...代码省略...        
    }    
    
    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        ...代码省略...
        //调用Instrumentation的callActivityOnPause方法,该方法最终会触发Activity的onPause方法   
        mInstrumentation.callActivityOnPause(r.activity);
        ...代码省略...
    }

    @Override
    public void handleStopActivity(ActivityClientRecord r, int configChanges,
            PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
        ...代码省略...       
        //继续调用performStopActivityInner方法     
        performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest, reason);
        ...代码省略...                
    }
    
    private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
            boolean saveState, boolean finalStateRequest, String reason) {
        ...代码省略...        
        //调用callActivityOnStop
        callActivityOnStop(r, saveState, reason);
        ...代码省略...
    }
    
    private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
        ...代码省略...
         //调用Activity的performStop方法
        r.activity.performStop(r.mPreserveWindow, reason);
        ...代码省略...       
    }

    @Override
    public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
            boolean getNonConfigInstance, String reason) {
        performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
        ...代码省略...       
    }

    void performDestroyActivity(ActivityClientRecord r, boolean finishing,
            int configChanges, boolean getNonConfigInstance, String reason) {
        ...代码省略...          
        if (!r.stopped) {
            callActivityOnStop(r, false /* saveState */, "destroy");
        }
        ...代码省略...      
        //调用Instrumentation的callActivityOnDestroy方法,该方法最终会触发Activity的OnDestroy方法   
        mInstrumentation.callActivityOnDestroy(r.activity);
        ...代码省略...      
    }
    
    @Override
    public void performRestartActivity(ActivityClientRecord r, boolean start) {
        if (r.stopped) {
        	//调用Activity的performRestart方法
            r.activity.performRestart(start, "performRestartActivity");
            if (start) {
                r.setState(ON_START);
            }
        }
    }
}

结合以上代码可以发现ActivityThread很多时候会进一步通过Instrumentation来触发Activity的生命周期回调。

4、简单来看下Instrumentation的相关源码。

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

public class Instrumentation {

    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);//调用Activity的performCreate方法
        postPerformCreate(activity);
    }
    
    public void callActivityOnStart(Activity activity) {
        activity.onStart();//调用Activity的onStart方法
    }
    
    public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();//调用Activity的onResume方法
        ...代码省略...
    }
    
    public void callActivityOnStop(Activity activity) {
        activity.onStop();//调用Activity的onResume方法
    }
    
    public void callActivityOnDestroy(Activity activity) {      
      activity.performDestroy();//调用Activity的performDestroy方法
  }
}    

5、最后来看下Activity和生命周期回调相关的方法

base/core/java/android/app/Activity.java

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
 
    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, IBinder assistToken,
            IBinder shareableActivityToken) {
        ...代码省略...
        mInstrumentation = instr;
        ...代码省略...
	}
	
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    	...代码省略...
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
    	...代码省略...        
    }
    
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    	...代码省略...        
    }
    
    final void performStart(String reason) {
    	...代码省略...       
    	//调用Instrumentation的callActivityOnPause方法,该方法最终会触发Activity的onStart方法        
        mInstrumentation.callActivityOnStart(this);
        ...代码省略...        
   }
   
    protected void onStart() {
          ...代码省略...      
    }
    
    final void performResume(String reason) {    
       ...代码省略...       
       //调用Instrumentation的callActivityOnResume方法,该方法最终会触发Activity的onResume方法           
       mInstrumentation.callActivityOnResume(this);
       ...代码省略...       
    }
    
    protected void onResume() {
        ...代码省略...      
    }
    
    protected void onPause() {
        ...代码省略...      
    }
    
    final void performStop(boolean preserveWindow, String reason) {
         ...代码省略...    
        //调用Instrumentation的callActivityOnStop方法,该方法最终会触发Activity的OnStop方法               
        mInstrumentation.callActivityOnStop(this);
         ...代码省略...    
    }
    
    protected void onStop() {
        ...代码省略...    
    }

    final void performDestroy() {
        ...代码省略...    
        onDestroy();
        ...代码省略...    
    }
    
    protected void onDestroy() {
        ...代码省略...    
    }
}

三、Activity和窗口动画相关的源码

1、在分析窗口动画和Window相关的源码之前,我们需要简单了解一下Activity是如何将窗口动画相关的参数传递给窗口的。

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
        
 	private Window mWindow;
 	
    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, IBinder assistToken,
            IBinder shareableActivityToken) {
        ...代码省略...
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        ...代码省略...
    }
    
    public Window getWindow() {
        return mWindow;//这里获取的是PhoneWindow
    }
    
    public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);//调用PhoneWindow的setContentView方法
        initWindowDecorActionBar();
    }

}

系统最早是在Activity的attach方法中创建其对应的PhoneWindow的,然后会在setContentView方法中调用PhoneWindow的setContentView方法。

2、PhoneWindow的setContentView方法如下所示。

base/core/java/com/android/internal/policy/PhoneWindow.java

public class PhoneWindow extends Window implements MenuBuilder.Callback {

    private final static int DEFAULT_BACKGROUND_FADE_DURATION_MS = 300;//默认的动效时间
    private static final Transition USE_DEFAULT_TRANSITION = new TransitionSet();//默认的窗口切换动效

    private Transition mEnterTransition = null;//进入动效
    private Transition mReturnTransition = USE_DEFAULT_TRANSITION;//返回动效
    private Transition mExitTransition = null;//退出动效
    private Transition mReenterTransition = USE_DEFAULT_TRANSITION;//从另一个Window返回当前Window的动效
    private Transition mSharedElementEnterTransition = null;//共享元素的进入动效
    private Transition mSharedElementReturnTransition = USE_DEFAULT_TRANSITION;//共享元素的返回动效
    private Transition mSharedElementExitTransition = null;//共享元素的退出动效
    private Transition mSharedElementReenterTransition = USE_DEFAULT_TRANSITION;//从另一个Window返回当前Window的共享元素动效
    private Boolean mAllowReturnTransitionOverlap;//是否允许返回动效
    private Boolean mAllowEnterTransitionOverlap;//是否允许进入动效
    private long mBackgroundFadeDurationMillis = -1;//转换动效的时间
    private Boolean mSharedElementsUseOverlay;  //是否允许共享元素动效
    
    @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();//调用installDecor
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }
		...代码省略...
    }

    private void installDecor() {
		...代码省略...
	   //检查设备是否支持活动(Activity)之间的转换过渡效果,旨在提供更为流畅和吸引人的界面转场动画。
	  if (hasFeature(FEATURE_ACTIVITY_TRANSITIONS)) {
	      if (mTransitionManager == null) {
	          final int transitionRes = getWindowStyle().getResourceId(
	                  R.styleable.Window_windowContentTransitionManager,
	                  0);
	          if (transitionRes != 0) {
	              final TransitionInflater inflater = TransitionInflater.from(getContext());
	              mTransitionManager = inflater.inflateTransitionManager(transitionRes,
	                      mContentParent);
	          } else {
	              mTransitionManager = new TransitionManager();
	          }
	      }
		 //和窗口相关的转换动效
	      mEnterTransition = getTransition(mEnterTransition, null,
	              R.styleable.Window_windowEnterTransition);
	      mReturnTransition = getTransition(mReturnTransition, USE_DEFAULT_TRANSITION,
	              R.styleable.Window_windowReturnTransition);
	      mExitTransition = getTransition(mExitTransition, null,
	              R.styleable.Window_windowExitTransition);
	      mReenterTransition = getTransition(mReenterTransition, USE_DEFAULT_TRANSITION,
	              R.styleable.Window_windowReenterTransition);
	      mSharedElementEnterTransition = getTransition(mSharedElementEnterTransition, null,
	              R.styleable.Window_windowSharedElementEnterTransition);
	      mSharedElementReturnTransition = getTransition(mSharedElementReturnTransition,
	              USE_DEFAULT_TRANSITION,
	              R.styleable.Window_windowSharedElementReturnTransition);
	      mSharedElementExitTransition = getTransition(mSharedElementExitTransition, null,
	              R.styleable.Window_windowSharedElementExitTransition);
	      mSharedElementReenterTransition = getTransition(mSharedElementReenterTransition,
	              USE_DEFAULT_TRANSITION,
	              R.styleable.Window_windowSharedElementReenterTransition);
	      if (mAllowEnterTransitionOverlap == null) {
	          mAllowEnterTransitionOverlap = getWindowStyle().getBoolean(
	                  R.styleable.Window_windowAllowEnterTransitionOverlap, true);
	      }
	      if (mAllowReturnTransitionOverlap == null) {
	          mAllowReturnTransitionOverlap = getWindowStyle().getBoolean(
	                  R.styleable.Window_windowAllowReturnTransitionOverlap, true);
	      }
	      if (mBackgroundFadeDurationMillis < 0) {
	          mBackgroundFadeDurationMillis = getWindowStyle().getInteger(
	                  R.styleable.Window_windowTransitionBackgroundFadeDuration,
	                  DEFAULT_BACKGROUND_FADE_DURATION_MS);
	      }
	      if (mSharedElementsUseOverlay == null) {
	          mSharedElementsUseOverlay = getWindowStyle().getBoolean(
	                  R.styleable.Window_windowSharedElementsUseOverlay, true);
	      }
	  }
    }
}

3、继续来看Activity和窗口动画相关的源码。

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
       
    ActivityTransitionState mActivityTransitionState = new ActivityTransitionState();
    SharedElementCallback mEnterTransitionListener = SharedElementCallback.NULL_CALLBACK;
    SharedElementCallback mExitTransitionListener = SharedElementCallback.NULL_CALLBACK;   

   final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ...代码省略...      
        mActivityTransitionState.readState(icicle);
      	...代码省略...
      	//将Window的进入动画存入mActivityTransitionState
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
      	...代码省略...
    }
   
   final void performStart(String reason) {
      	...代码省略...
        //将Window的进入动画存入mActivityTransitionState
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
      	...代码省略...
        mActivityTransitionState.enterReady(this);
      	...代码省略...
    }
    
    protected void onResume() {
      	...代码省略...
        mActivityTransitionState.onResume(this);
        ...代码省略...
	}

	protected void onStop() {
        ...代码省略...
        mActivityTransitionState.onStop(this);
        ...代码省略...
   }

 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/583601.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

# 使用 spring boot 时,@Autowired 注解 自动装配注入时,变量报红解决方法:

使用 spring boot 时&#xff0c;Autowired 注解 自动装配注入时&#xff0c;变量报红解决方法&#xff1a; 1、使用 Resource 代替 Autowired 注解&#xff0c;根据类型注入改为根据名称注入&#xff08;建议&#xff09;。 2、在 XXXMapper 上添加 Repository 注解&#xff0…

(2024,一致性模型,强化学习,MDP,DDPO)一致性模型的强化学习:更快的奖励引导文本到图像生成

RL for Consistency Models: Faster Reward Guided Text-to-Image Generation 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 部分图像上传缓慢&#xff0c;可看原论文或在 EDPJ 查看 目录 …

2024/4/29 英语每日一段

Many have turned to cheaper, hand-rolled tobacco instead of normal cigarettes, with young women telling The Times that the habit was a social way to get rid of “anxious energy”. The news comes as the government voted on Tuesday to phase out smoking in Br…

RCE复习(ctfhub下)

先了解一下命令注入的知识点&#xff1a; 知识点 1、常见的拼接符 A ; B 先执行A&#xff0c;再执行BA & B 简单的拼接A | B 显示B的执行结果A&&B A执行成功之后才会执行BA || B A执行失败之后才会执行B , 在特殊情况下可代替空格…

pytorch 实现语义分割 PSPNet

语意分割是指一张图片上包含多个物体&#xff0c;通过语义分割可以识别物体分类、物体名称、像素识别的任务。和物体检测不同&#xff0c;他不会将物体框出来&#xff0c;而是根据像素的归属把物体标注出来。PSPNet 的输入是一张图片&#xff0c;例如300500&#xff0c;那么输出…

Redis基本數據結構 ― List

Redis基本數據結構 ― List 介紹常用命令範例1. 將元素推入List中2. 取得List內容3. 彈出元素 介紹 Redis中的List結構是一個雙向鏈表。 LPUSH LPOP StackLPUSH RPOP QueueLPUSH BRPOP Queue(消息隊列) 常用命令 命令功能LPUSH將元素推入列表左端RPUSH將元素推入列表右…

特别推荐一个学习开发编程的网站

http://www.somecore.cn/ 为开发人员提供一系列好看的技术备忘单&#xff0c;方便开发过程中速查基本语法、快捷键、命令&#xff0c;节省查找时间&#xff0c;提高开发效率。 【人生苦短&#xff0c;抓住重点】

Java 面向对象—重载和重写/覆盖(面试)

重载和重写/覆盖&#xff1a; 重载&#xff08;overload&#xff09;&#xff1a; Java重载是发生在本类中的&#xff0c;允许同一个类中&#xff0c;有多个同名方法存在&#xff0c;方法名可以相同&#xff0c;方法参数的个数和类型不同&#xff0c;即要求形参列表不一致。重载…

有趣的 CSS 图标整合技术!sprites精灵图,css贴图定位

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端工具”&#xff0c;可获取 Web 开发工具合…

【C语言进阶】程序编译中的预处理操作

&#x1f4da;作者简介&#xff1a;爱编程的小马&#xff0c;正在学习C/C&#xff0c;Linux及MySQL.. &#x1f4da;以后会将数据结构收录为一个系列&#xff0c;敬请期待 ● 本期内容讲解C语言中程序预处理要做的事情 目录 1.1 预处理符号 1.2 #define 1.2.1 #define定义标识…

数据结构(01)——链表OJ

目录 移除链表元素 思路1 不创建虚拟头节点 思路2 创建虚拟头节点 反转链表 寻找链表中间节点 判断链表是否相交 回文链表 环形链表 环形链表|| 移除链表元素 . - 力扣&#xff08;LeetCode&#xff09; 要想移除链表的元素&#xff0c;那么只需要将目标节点的前一…

07_for循环返回值while循环

文章目录 1.循环返回值2.yield接收for返回值3.scala调用yield方法创建线程对象4.scala中的while循环5.scala中的流程控制 1.循环返回值 for循环返回值是Unit 原因是防止产生歧义&#xff1b; 2.yield接收for返回值 // 2.yield关键字打破循环&#xff0c;可以使for循环输出…

智慧农业设备——虫情监测系统

随着科技的不断进步和农业生产的日益现代化&#xff0c;智慧农业成为了新时代农业发展的重要方向。其中&#xff0c;虫情监测系统作为智慧农业的重要组成部分&#xff0c;正逐渐受到广大农户和农业专家的关注。 虫情监测系统是一种基于现代传感技术、图像识别技术和大数据分析技…

面试笔记——线程池

线程池的核心参数&#xff08;原理&#xff09; public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)corePoolSize …

25计算机考研院校数据分析 | 四川大学

四川大学(Sichuan University)简称“川大”&#xff0c;由中华人民共和国教育部直属&#xff0c;中央直管副部级建制&#xff0c;是世界一流大学建设高校、985工程”、"211工程"重点建设的高水平综合性全国重点大学&#xff0c;入选”2011计划"、"珠峰计划…

PostgreSQL的学习心得和知识总结(一百四十)|深入理解PostgreSQL数据库 psql工具 \set 变量内部及HOOK机制

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

【能力展现】魔改ZXING源码实现商业级DM码检测能力

学习《OpenCV应用开发&#xff1a;入门、进阶与工程化实践》一书 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; 什么是DM码 dataMatrix是一种二维码&#xff0c;原名datacode&#xff0c;由美国国际资料公司于1989年发明。dataMatrix二维码…

GuildFi升级为Zentry的背后 链游公会的探索与转型

​链游即区块链游戏&#xff0c;指依托区块链技术构建的游戏产品。其与传统游戏的最大区别在于区块链的去中心化特性对玩家的资产有着天然的确权行为&#xff0c;因此玩家在链游中的资产是作为玩家的个人资产存在。较于 GameFi 来说&#xff0c;链游的包含范围更大&#xff0c;…

吴恩达机器学习笔记:第 8 周-14降维(Dimensionality Reduction) 14.3-14.5

目录 第 8 周 14、 降维(Dimensionality Reduction)14.3 主成分分析问题14.4 主成分分析算法14.5 选择主成分的数量 第 8 周 14、 降维(Dimensionality Reduction) 14.3 主成分分析问题 主成分分析(PCA)是最常见的降维算法。 在 PCA 中&#xff0c;我们要做的是找到一个方向…

【高校科研前沿】华东师大白开旭教授博士研究生李珂为一作在RSE发表团队最新成果:基于波谱特征优化的全球大气甲烷智能反演技术

文章简介 论文名称&#xff1a;Developing unbiased estimation of atmospheric methane via machine learning and multiobjective programming based on TROPOMI and GOSAT data&#xff08;基于TROPOMI和GOSAT数据&#xff0c;通过机器学习和多目标规划实现大气甲烷的无偏估…