一、通过ActivityOptions获取Activity对应的打开动画
1、我们可以通过ActivityOptions类,实现打开Activity的时候有对应的缩放动画。
java
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
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方法,可以将自己转化成对应的参数类型。
java
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的生命回调的。
java
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
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生命周期回调相关的方法。
java
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
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
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是如何将窗口动画相关的参数传递给窗口的。
java
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
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和窗口动画相关的源码。
java
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);
...代码省略...
}
}