精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

了解Activity啟動過程,從startActivity到ATMS的高效協作

移動開發 Android
在Android的不同版本中,啟動流程可能會有所不同,并且可能涉及到更多的細節和組件。此外,如果啟動的是一個根Activity(例如從Launcher啟動),那么流程中可能還包括應用進程的創建等步驟。

在Android系統中,啟動一個Activity無論是從應用內部啟動Activity,還是通過桌面程序(Launcher)啟動,都需要通過調用startActivity方法來發起啟動請求。

啟動請求的發起

  1. 「應用內部啟動Activity」:

當應用內部需要啟動一個新的Activity時,開發者會調用startActivity方法,并傳遞一個包含目標Activity信息的Intent對象。

這個Intent對象可以指定要啟動的Activity的類名、傳遞的數據、附加的extras等。

調用startActivity后,系統會開始處理啟動請求,并按照Activity啟動流程進行后續操作。

  1. 「Launcher啟動Activity」:
  • Launcher是Android系統的桌面程序,它負責顯示已安裝的應用程序圖標,并提供用戶與應用程序交互的入口。

  • 當用戶從Launcher點擊一個應用程序圖標時,Launcher會創建一個新的Intent,用于啟動該應用程序的主Activity(通常是根Activity)。

  • 然后,Launcher調用startActivity方法,并將該Intent傳遞給系統,以啟動目標Activity。

在兩種情況下,啟動請求的發起都是通過調用startActivity方法實現的。這個方法會觸發一系列的操作,包括將啟動請求傳遞給ActivityTaskManagerService(ATMS),進行線程切換和消息處理,以及最終完成Activity的初始化和顯示。無論是startActivity還是startActivityForResult最終都是調用startActivityForResult。

圖片圖片

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback,
        AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        //...
        
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        // mParent 是Activity類型,是當前Activity的父類
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            // 調用Instrumentation.execStartActivity啟動activity
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            //...
            
        } else {
            //...

        }
    }
}

startActivityForResult中調用Instrumentation.execStartActivity方法。Activity中的mInstrumentation是在attach()方法中初始化,由ActivityThread傳入,其作用是通過遠程服務調用啟動activity,連接ActivityThread與activity,處理activity生命周期回調。

// Instrumentation主要用來監控應用程序和系統的交互,比如調用ATMS啟動activity,回調生命周期
public class Instrumentation {

    public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
        //...

        try {
            //...
            
            // 通過ATMS遠程調用startActivity
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getOpPackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

    /**
     * 根據result判斷當前能否啟動activity,不能則拋出異常
     */
    public static void checkStartActivityResult(int res, Object intent) {
        if (!ActivityManager.isStartResultFatalError(res)) {
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    // 沒有在manifest中聲明
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startVoiceActivity does not match active session");
            case ActivityManager.START_VOICE_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start voice activity on a hidden session");
            case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startAssistantActivity does not match active session");
            case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start assistant activity on a hidden session");
            case ActivityManager.START_CANCELED:
                throw new AndroidRuntimeException("Activity could not be started for "
                        + intent);
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }
}
@SystemService(Context.ACTIVITY_TASK_SERVICE)
public class ActivityTaskManager {
    /**
     * IActivityTaskManager是一個Binder,用于和system_server進程中的ActivityTaskManagerService通信
     */
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };
}

當請求到達ATMS時,ATMS會首先檢查該請求是否合法,包括檢查Intent的有效性、權限等。一旦請求被驗證為有效,ATMS會進一步處理這個請求。

處理過程中,ATMS會根據當前系統的狀態和任務棧的情況來決定如何響應這個啟動請求。例如,它可能會決定創建一個新的Activity實例,或者將已存在的Activity實例帶到前臺。ATMS還會與ActivityManagerService(AMS)進行交互,以協調應用程序組件的生命周期管理。AMS負責跟蹤和管理這些組件的生命周期,確保它們按照預期的方式運行。

Activity的初始化與生命周期管理

當Activity啟動請求到達ActivityTaskManagerService(ATMS)并被驗證為有效后,ATMS會通知相應的應用進程進行Activity的初始化。

// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    public final int startActivity(IApplicationThread caller, String callingPackage,
      String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
      String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
      Bundle bOptions) {
      return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
              resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
              UserHandle.getCallingUserId());
    }

    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
        @Nullable String callingFeatureId, Intent intent, String resolvedType,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        // 判斷調用者進程是否被隔離
        enforceNotIsolatedCaller("startActivityAsUser");
        
        // 檢查調用者權限
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");


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

ATMS通過一系列方法最終調到startActivityAsUser方法,先檢查調用者權限,再通過getActivityStartController().obtainStarter創建ActivityStarter類,把參數設置到ActivityStarter.Request類中,最后執行ActivityStarter.execute()方法。

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
class ActivityStarter {

    int execute() {
        try {
            //...

            int res;
            synchronized (mService.mGlobalLock) {
                //...
                
                res = executeRequest(mRequest);

                //...
            }
        } finally {
            onExecutionComplete();
        }
    }


    private int executeRequest(Request request) {
        // 判斷啟動的理由不為空
        if (TextUtils.isEmpty(request.reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }

        // 獲取調用的進程
        WindowProcessController callerApp = null;
        if (caller != null) {
          callerApp = mService.getProcessController(caller);
          if (callerApp != null) {
              // 獲取調用進程的pid和uid并賦值
              callingPid = callerApp.getPid();
              callingUid = callerApp.mInfo.uid;
          } else {
              err = ActivityManager.START_PERMISSION_DENIED;
          }
        }

        final int userId = aInfo != null && aInfo.applicationInfo != null
              ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;

        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
          // 獲取調用者所在的ActivityRecord
          sourceRecord = mRootWindowContainer.isInAnyStack(resultTo);
          if (sourceRecord != null) {
              if (requestCode >= 0 && !sourceRecord.finishing) {
                  //requestCode = -1 則不進入
                  resultRecord = sourceRecord;
              }
          }
        }

        final int launchFlags = intent.getFlags();
        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
           // activity執行結果的返回由源Activity轉換到新Activity, 不需要返回結果則不會進入該分支
        }

        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
           // 從Intent中無法找到相應的Component
           err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }

        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
           // 從Intent中無法找到相應的ActivityInfo
           err = ActivityManager.START_CLASS_NOT_FOUND;
        }

        
        //執行后resultStack = null
        final ActivityStack resultStack = resultRecord == null
              ? null : resultRecord.getRootTask();

        //權限檢查
        if (mService.mController != null) {
            try {
                Intent watchIntent = intent.cloneFilter();
                abort |= !mService.mController.activityStarting(watchIntent,
                      aInfo.applicationInfo.packageName);
            } catch (RemoteException e) {
              mService.mController = null;
            }
        }

        if (abort) {
            //權限檢查不滿足,才進入該分支則直接返回;
            return START_ABORTED;
        

        if (aInfo != null) {
            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                  aInfo.packageName, userId)) {
             
                // 向PKMS獲取啟動Activity的ResolveInfo
                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
                      computeResolveFilterUid(
                              callingUid, realCallingUid, request.filterCallingUid));
                // 向PKMS獲取啟動Activity的ActivityInfo
                aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
                      null /*profilerInfo*/);

            }
        }


        // 創建即將要啟動的Activity的描述類ActivityRecord
        final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
              callingPackage, callingFeatureId, intent, resolvedType, aInfo,
              mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
              request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
              sourceRecord);
        mLastStartActivityRecord = r;


        // 調用 startActivityUnchecked
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

        if (request.outActivity != null) {
            request.outActivity[0] = mLastStartActivityRecord;
        }

        return mLastStartActivityResult;
    }
}

在ActivityStarter中調用executeRequest方法,先做一系列檢查,包括進程檢查、intent檢查、權限檢查、向PKMS獲取啟動Activity的ActivityInfo等信息,調用startActivityUnchecked方法開始對要啟動的activity進行任務棧管理。

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    

    try {

        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
    } finally {
        
        //...
    }

    //...

    return result;
}

ActivityRecord mStartActivity;

private ActivityStack mSourceStack;
private ActivityStack mTargetStack;
private Task mTargetTask;


// 主要處理棧管理相關的邏輯
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
                     IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                     int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                     boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    // 初始化啟動Activity的各種配置,在初始化前會重置各種配置再進行配置,
    // 這些配置包括:ActivityRecord、Intent、Task和LaunchFlags(啟動的FLAG)等等
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
          voiceInteractor, restrictedBgActivity);

    // 給不同的啟動模式計算出mLaunchFlags
    computeLaunchingTaskFlags();

    // 主要作用是設置ActivityStack
    computeSourceStack();

    // 將mLaunchFlags設置給Intent
    mIntent.setFlags(mLaunchFlags);

    // 確定是否應將新活動插入現有任務。如果不是,則返回null,
    // 或者返回帶有應將新活動添加到其中的任務的ActivityRecord。
    final Task reusedTask = getReusableTask();


    // 如果reusedTask為null,則計算是否存在可以使用的任務棧
    final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
    final boolean newTask = targetTask == null; // 啟動Activity是否需要新創建棧
    mTargetTask = targetTask;

    computeLaunchParams(r, sourceRecord, targetTask);

    // 檢查是否允許在給定任務或新任務上啟動活動。
    int startResult = isAllowedToStart(r, newTask, targetTask);
    if (startResult != START_SUCCESS) {
        return startResult;
    }


    final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
    if (topStack != null) {
        // 檢查正在啟動的活動是否與當前位于頂部的活動相同,并且應該只啟動一次
        startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    }

    if (mTargetStack == null) {
        // 復用或者創建堆棧
        mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
    }
    if (newTask) {
        // 新建一個task
        final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
              ? mSourceRecord.getTask() : null;
        setNewTask(taskToAffiliate);
        if (mService.getLockTaskController().isLockTaskModeViolation(
              mStartActivity.getTask())) {
            Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
            return START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
    } else if (mAddingToTask) {
        // 復用之前的task
        addOrReparentStartingActivity(targetTask, "adding to task");
    }

    

    // 檢查是否需要觸發過渡動畫和開始窗口
    mTargetStack.startActivityLocked(mStartActivity,
          topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
          mKeepCurTransition, mOptions);


    if (mDoResume) {

        // 調用RootWindowContainer的resumeFocusedStacksTopActivities方法
        mRootWindowContainer.resumeFocusedStacksTopActivities(
              mTargetStack, mStartActivity, mOptions);
    }


    return START_SUCCESS;
}


private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
                           boolean doResume, int startFlags, ActivityRecord sourceRecord,
                           IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                           boolean restrictedBgActivity) {

    reset(false /* clearRequest */); 
    mStartActivity = r; 
    mIntent = r.intent; 
    mSourceRecord = sourceRecord; 
    mLaunchMode = r.launchMode; 
    // 啟動Flags
    mLaunchFlags = adjustLaunchFlagsToDocumentMode(
          r, LAUNCH_SINGLE_INSTANCE == mLaunchMode,
          LAUNCH_SINGLE_TASK == mLaunchMode, mIntent.getFlags());
    mInTask = inTask;
    // ...
}


private void computeLaunchingTaskFlags() {
    if (mInTask == null) {
        if (mSourceRecord == null) {
            if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        } else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        }
    }
}

// 設置ActivityStack
private void computeSourceStack() {
    if (mSourceRecord == null) {
        mSourceStack = null;
        return;
    }
    if (!mSourceRecord.finishing) {
        mSourceStack = mSourceRecord.getRootTask();
        return;
    }

    if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
        mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        mNewTaskInfo = mSourceRecord.info;

        final Task sourceTask = mSourceRecord.getTask();
        mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
    }
    mSourceRecord = null;
    mSourceStack = null;
}

private Task getReusableTask() {
    // If a target task is specified, try to reuse that one
    if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
        Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
        if (launchTask != null) {
            return launchTask;
        }
        return null;
    }

    //標志位,如果為true,說明要放入已經存在的棧,
    // 可以看出,如果是設置了FLAG_ACTIVITY_NEW_TASK 而沒有設置 FLAG_ACTIVITY_MULTIPLE_TASK,
    // 或者設置了singleTask以及singleInstance
    boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
    // 重新檢驗
    putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
    ActivityRecord intentActivity = null;
    if (putIntoExistingTask) {
        if (LAUNCH_SINGLE_INSTANCE == mLaunchMode) {
            //如果是 singleInstance,那么就找看看之前存在的該實例,找不到就為null
            intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
                    mStartActivity.isActivityTypeHome());
        } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
            // For the launch adjacent case we only want to put the activity in an existing
            // task if the activity already exists in the history.
            intentActivity = mRootWindowContainer.findActivity(mIntent, mStartActivity.info,
                    !(LAUNCH_SINGLE_TASK == mLaunchMode));
        } else {
            // Otherwise find the best task to put the activity in.
            intentActivity =
                    mRootWindowContainer.findTask(mStartActivity, mPreferredTaskDisplayArea);
        }
    }

    if (intentActivity != null
            && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
            && intentActivity.getDisplayArea() != mPreferredTaskDisplayArea) {
        // Do not reuse home activity on other display areas.
        intentActivity = null;
    }

    return intentActivity != null ? intentActivity.getTask() : null;
}

// 計算啟動的Activity的棧
private Task computeTargetTask() {
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        // 返回null,應該新創建一個Task,而不是使用現有的Task
        return null;
    } else if (mSourceRecord != null) {
        // 使用源Activity的task
        return mSourceRecord.getTask();
    } else if (mInTask != null) {
        // 使用啟動時傳遞的task
        return mInTask;
    } else {
        // 理論上的可能,不可能走到這里
        final ActivityStack stack = getLaunchStack(mStartActivity, mLaunchFlags,
                null /* task */, mOptions);
        final ActivityRecord top = stack.getTopNonFinishingActivity();
        if (top != null) {
            return top.getTask();
        } else {
            // Remove the stack if no activity in the stack.
            stack.removeIfPossible();
        }
    }
    return null;
}

在startActivityInner方法中,根據啟動模式和flag等條件判斷要啟動的activity的ActivityRecord是加入現有的Task棧中或創建新的Task棧。在為Activity準備好Task棧后,調用RootWindowContainer.resumeFocusedStacksTopActivities方法。

class RootWindowContainer extends WindowContainer<DisplayContent>
      implements DisplayManager.DisplayListener {

    boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        //...
        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackInDisplayArea()
                || getTopDisplayFocusedStack() == targetStack)) {
            // 調用ActivityStack.resumeTopActivityUncheckedLocked
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        //...
        return result;
    }
}

class ActivityStack extends Task {

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
      if (mInResumeTopActivity) {
          // Don't even start recurscheduleTransactionsing.
          return false;
      }

      boolean result = false;
      try {
          mInResumeTopActivity = true;
          // 繼續調用resumeTopActivityInnerLocked
          result = resumeTopActivityInnerLocked(prev, options);

          final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
          if (next == null || !next.canTurnScreenOn()) {
              checkReadyForSleep();
          }
      } finally {
          mInResumeTopActivity = false;
      }

      return result;
  }

  private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

      // Find the next top-most activity to resume in this stack that is not finishing and is
      // focusable. If it is not focusable, we will fall into the case below to resume the
      // top activity in the next focusable task.
      // 在當前Task棧中找到最上層正在運行的activity,如果這個activity沒有獲取焦點,那這個activity將會被重新啟動
      ActivityRecord next = topRunningActivity(true /* focusableOnly */);
      final boolean hasRunningActivity = next != null;

      if (next.attachedToProcess()) {
          ...
      } else {
          ...
          // 調用StackSupervisor.startSpecificActivity
          mStackSupervisor.startSpecificActivity(next, true, true);
      }
      return true;
  }
}

ActivityStack用于單個活動棧的管理,最終調到ActivityStackSupervisor.startSpecificActivity()。

public class ActivityStackSupervisor implements RecentTasks.Callbacks {

    // 檢查啟動Activity所在進程是否有啟動,沒有則先啟動進程
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // 根據processName和Uid查找啟動Activity的所在進程
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;

        if (wpc != null && wpc.hasThread()) {
            // 進程已經存在,則直接啟動Activity
            try {
                // 啟動Activity ,并返回
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
               ...
            }
            knownToBeDead = true;
        }

        // 所在進程沒創建則調用ATMS.startProcessAsync創建進程并啟動Activity
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

    // 啟動Activity的進程存在,則執行此方法 
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                                    boolean andResume, boolean checkConfig) throws RemoteException {

        ...

        // 創建活動啟動事務
        // proc.getThread()是一個IApplicationThread對象,可以通過ClientTransaction.getClient()獲取
        final ClientTransaction clientTransaction = ClientTransaction.obtain(
                proc.getThread(), r.appToken);

        // 為事務設置Callback,為LaunchActivityItem,在客戶端時會被調用
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                System.identityHashCode(r), r.info,
                // TODO: Have this take the merged configuration instead of separate global
                // and override configs.
                mergedConfiguration.getGlobalConfiguration(),
                mergedConfiguration.getOverrideConfiguration(), r.compat,
                r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

        // 設置所需的最終狀態
        final ActivityLifecycleItem lifecycleItem;
        if (andResume) {
            lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
        } else {
            lifecycleItem = PauseActivityItem.obtain();
        }
        clientTransaction.setLifecycleStateRequest(lifecycleItem);

        // 執行事件,調用ClientLifecycleManager.scheduleTransaction
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);

        ...
        return true;
    }
}

在ActivityStackSupervisor中,先檢查要啟動activity的進程是否存在,存在則調用realStartActivityLocked方法,通過ClientTransaction事務回調ApplicationThread.scheduleTransaction方法;進程不存在則創建進程。

Activity的顯示

// 主要是處理AMS端的請求
private class ApplicationThread extends IApplicationThread.Stub {
    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }
}

// ActivityThread的父類
public abstract class ClientTransactionHandler {

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        // 發送EXECUTE_TRANSACTION消息
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}

// 它管理應用程序進程中主線程的執行,根據活動管理器的請求,在其上調度和執行活動、廣播和其他操作。
public final class ActivityThread extends ClientTransactionHandler {

    class H extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    // 調用TransactionExecutor.execute去處理ATMS階段傳過來的ClientTransaction
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    break;
            }
        }
    }
}

public class TransactionExecutor {
    public void execute(ClientTransaction transaction) {
        //...
        // 調用傳過來的ClientTransaction事務的Callback
        executeCallbacks(transaction);

        executeLifecycleState(transaction);
    }

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            ...
            // 調用LaunchActivityItem.execute
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ...
        }
    }
}

public class LaunchActivityItem extends ClientTransactionItem {
    public void execute(ClientTransactionHandler client, IBinder token,
                        PendingTransactionActions pendingActions) {
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
        // 調用ActivityThread.handleLaunchActivity
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    }
}

ApplicationThread最后調用在ATMS階段設置的ClientTransaction的CallBack的execute方法,即LaunchActivityItem.execute方法,此時創建一個ActivityClientRecord對象,然后通過ActivityThread.handleLaunchActivity開啟真正的Actvity啟動。

public final class ActivityThread extends ClientTransactionHandler {
    // ActivityThread啟動Activity的過程
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
                                         PendingTransactionActions pendingActions, Intent customIntent) {
        // ...
        WindowManagerGlobal.initialize();
        // 啟動Activity
        final Activity a = performLaunchActivity(r, customIntent);
    
        if (a != null) {
           ...
        } else {
            // 啟動失敗,調用ATMS停止Activity啟動
            try {
                ActivityTaskManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    
    return a;
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 獲取ActivityInfo類
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        // 獲取APK文件的描述類LoadedApk
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    // 啟動的Activity的ComponentName類
    ComponentName component = r.intent.getComponent();

    // 創建要啟動Activity的上下文環境
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 用類加載器來創建該Activity的實例
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        // ...
    } catch (Exception e) {
        // ...
    }

    try {
        // 創建Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (activity != null) {
            // 初始化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);

            ...
            // 調用Instrumentation的callActivityOnCreate方法來啟動Activity
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
          ...
        }
      ...

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        ...
    }

    return activity;
}


public class Instrumentation {

    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        // 調用Activity的performCreate
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
}

public class Activity extends ContextThemeWrapper
      implements LayoutInflater.Factory2,
      Window.Callback, KeyEvent.Callback,
      OnCreateContextMenuListener, ComponentCallbacks2,
      Window.OnWindowDismissedCallback,
      AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    @UnsupportedAppUsage
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ...
        // 調用onCreate方法
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }

}

當初始化完成后,Activity的界面會被繪制并顯示到屏幕上。此時,用戶可以與Activity進行交互。

總結

  1. 「啟動請求的發起」:

無論是從應用內部啟動Activity,還是通過桌面程序(Launcher)啟動,都需要通過調用startActivity方法來發起啟動請求。

這個請求包含了要啟動的Activity的信息,通常通過Intent對象來傳遞。

  1. 「請求到達ActivityTaskManagerService(ATMS)」:
  • 當啟動請求被發起后,它會首先到達ActivityTaskManagerService(ATMS)。

  • ATMS是負責管理Activity生命周期和任務棧的系統服務。

  1. 「線程切換與消息處理」:

  • 在ATMS處理啟動請求的過程中,可能涉及到線程切換和消息處理。

  • 例如,將請求從應用線程切換到系統服務線程,或者通過消息隊列來處理請求。

  1. 「Activity的初始化與生命周期管理」:

  • 一旦ATMS決定了要啟動哪個Activity,它會通知相應的應用進程進行Activity的初始化。

  • 這包括創建Activity的實例、加載布局、初始化組件等。

  • 同時,Activity的生命周期方法(如onCreate、onStart、onResume等)也會被調用,以確保Activity的正確初始化和狀態管理。

  1. 「Activity的顯示」:

  • 當初始化完成后,Activity的界面會被繪制并顯示到屏幕上。

  • 此時,用戶可以與Activity進行交互。

在Android的不同版本中,啟動流程可能會有所不同,并且可能涉及到更多的細節和組件。此外,如果啟動的是一個根Activity(例如從Launcher啟動),那么流程中可能還包括應用進程的創建等步驟。Activity的啟動流程是一個涉及多個組件和服務的復雜過程,它確保了Android應用程序能夠正確地創建、初始化和顯示Activity,從而為用戶提供流暢和一致的體驗。

責任編輯:武曉燕 來源: 沐雨花飛蝶
相關推薦

2023-03-24 14:52:27

AbilityPage應用

2014-06-23 10:31:09

Android啟動過程

2011-09-05 17:35:18

MTK啟動過程RTOS

2011-07-28 10:34:38

Cocoa 程序 啟動

2021-07-02 06:34:53

Go語言sysmon

2011-06-28 13:27:13

ARM Linux

2009-12-03 10:00:46

Linux系統啟動

2010-07-05 17:38:39

IIS 7.0 FTP

2012-08-16 09:07:57

Erlang

2018-03-13 13:00:03

Linux運維啟動分析

2012-02-20 14:47:08

JavaPlay

2023-12-09 08:58:30

AndroidActivity啟動模式

2024-09-11 09:25:03

Tomcat組件PREP

2010-05-06 14:05:15

Unix系統

2021-09-28 15:03:06

Linux內核arm

2020-03-19 08:59:15

SpringMVC啟動過程

2019-05-27 14:43:49

Tomcat架構部署

2018-10-18 14:06:15

Linux系統過程

2020-04-20 21:30:51

Tomcat部署架構

2009-08-11 09:03:45

Windows 7系統啟動
點贊
收藏

51CTO技術棧公眾號

懂色av蜜臀av粉嫩av喷吹| 蜜桃传媒一区二区亚洲av| 国产在线1区| 风间由美性色一区二区三区| 午夜伦理精品一区| 欧美精品日韩在线| 高清日韩欧美| 精品视频在线免费| 国产一二三区在线播放| 你懂的在线视频| 国内精品久久久久影院色| 国内伊人久久久久久网站视频 | 特一级黄色大片| 欧美日韩在线观看视频小说| 日韩欧美成人激情| 日本中文字幕高清| 岛国av在线网站| 一区免费观看视频| 欧美成人蜜桃| 丰满熟妇人妻中文字幕| 日产国产高清一区二区三区 | 久久免费少妇高潮99精品| 国产欧美一区二区精品久久久| 欧美一区二区三区视频免费播放| 男人亚洲天堂网| 国产第一页在线| 中文字幕欧美日本乱码一线二线| 国产一区二区免费在线观看| 亚洲专区在线播放| 久久激情婷婷| 97在线视频一区| 青娱乐国产精品| 99视频精品全国免费| 亚洲日韩欧美视频一区| 国产毛片毛片毛片毛片毛片毛片| 久久九九精品视频| 欧美日韩免费观看一区二区三区| 玩弄japan白嫩少妇hd| 国产极品在线观看| 亚洲第一久久影院| 成人区一区二区| 在线中文字幕视频观看| 最新日韩在线视频| 一区二区三区的久久的视频| 国产h视频在线观看| 久久久久高清精品| 日本精品国语自产拍在线观看| 高h震动喷水双性1v1| 国产大陆精品国产| 91麻豆精品秘密入口| 国产一区二区三区中文字幕| 久久国产精品99精品国产| 国产精品男女猛烈高潮激情| 影音先锋在线国产| 香蕉精品999视频一区二区| 91精品国产色综合| 日韩三级视频在线| 亚洲欧美日韩国产一区| 欧美最近摘花xxxx摘花| 亚洲婷婷综合网| 三级欧美在线一区| 国产精品国产三级国产aⅴ9色 | 欧美精品中文字幕一区二区| 亚洲人妻一区二区三区| 久久尤物电影视频在线观看| 日本精品一区二区| 日本中文字幕电影在线免费观看 | 一区在线电影| 黄色av电影在线播放| 亚洲精品乱码久久久久久久久| 欧美做受777cos| 国产福利在线免费观看| 一本到不卡免费一区二区| 日韩欧美在线免费观看视频| 成人国产激情| 日韩美女主播在线视频一区二区三区 | 日本成人在线免费视频| 制服诱惑亚洲| 制服丝袜成人动漫| 大尺度在线观看| 国产精品亚洲片在线播放| 亚洲欧美另类中文字幕| 欧美另类69xxxx| 午夜日韩电影| 26uuu日韩精品一区二区| 中文字字幕在线中文乱码| 国产一区久久久| 精品在线视频一区二区三区| 99se视频在线观看| 亚洲二区在线观看| 嫩草影院国产精品| 国产精品成人自拍| 综合国产在线观看| 欧美成人aaaaⅴ片在线看| 日本亚洲三级在线| 99在线视频免费观看| 国产视频在线看| 亚洲综合成人网| 韩国视频一区二区三区| 成人台湾亚洲精品一区二区| 在线观看视频99| 国产网站在线看| 麻豆国产欧美一区二区三区| 国内一区在线| 老司机在线视频二区| 岛国av在线不卡| 亚洲欧美激情一区二区三区| 精品久久影视| 久久久久久久影院| 97caocao| 国产亚洲短视频| 欧美无砖专区免费| 二区三区精品| 中国china体内裑精亚洲片| 国产在线拍揄自揄拍无码视频| 日本中文字幕一区二区视频| 狠狠色综合色区| 黄色一级片在线观看| 一本大道av一区二区在线播放 | 亚洲视频国产精品| 中文字幕日韩av| 国产免费一级视频| 99精品在线免费| 黄色网在线视频| 中文字幕日韩亚洲| 色yeye香蕉凹凸一区二区av| 中文字幕精品三级久久久| 高潮精品一区videoshd| 桥本有菜av在线| 国产一区二区三区四区五区3d| 亚洲精品美女久久久| 中文字幕第28页| 国产一区二区免费在线| 中文字幕99| 日本黄色成人| 久久久999国产| 亚洲视频在线观看一区二区| 亚洲国产高清在线| 69久久久久久| 色777狠狠狠综合伊人| 国产精品视频大全| 亚洲成人三级| 欧美久久久影院| 亚洲精品电影院| 国产在线视频一区二区三区| 国产又大又长又粗又黄| 在线观看亚洲精品福利片| 日韩网站免费观看| 91成年人视频| 亚洲男人天堂av| 杨幂一区二区国产精品| 亚洲一级黄色| 久久精品成人一区二区三区蜜臀| 国产在线精彩视频| 亚洲精品一区中文| 久久影视中文字幕| 中文av一区二区| 色天使在线观看| 亚洲综合激情在线| 99精品国产高清一区二区| 日韩电影免费观看| 日韩电视剧在线观看免费网站 | 俺来也官网欧美久久精品| 精品国精品国产尤物美女| 国产精品23p| 久久亚洲一区二区三区明星换脸 | 久久精品亚洲无码| 26uuu另类欧美亚洲曰本| 成人免费视频久久| 欧美黄色大片在线观看| 999国内精品视频在线| 国产精品蜜芽在线观看| 亚洲欧美制服丝袜| 一区二区不卡视频在线观看| 一区二区三区精品在线观看| a天堂视频在线观看| 日韩精品一卡二卡三卡四卡无卡| 亚洲视频导航| 99精品中文字幕在线不卡| 欧洲中文字幕国产精品| 日本天堂在线观看| 精品国产1区二区| 波多野结衣一二区| 亚洲激情五月婷婷| 中文字幕狠狠干| 韩日av一区二区| 777精品久无码人妻蜜桃| 精品高清在线| 国产成人精品福利一区二区三区| sis001欧美| 九九精品在线观看| 久久天堂电影| 欧美成人激情免费网| 免费视频网站在线观看入口| 亚洲欧美色综合| 亚洲久久久久久久| 粉嫩13p一区二区三区| 国产精品视频黄色| 亚洲大胆视频| 久久久一二三四| 一本色道久久综合亚洲精品酒店 | 亚洲色图在线播放| 3d动漫精品啪啪一区二区下载| 久久99久久99小草精品免视看| 男人添女人下面高潮视频| 久久精品久久久| 日韩av电影免费在线| av成人资源| 成人福利网站在线观看| 欧美日韩国产v| 国模精品视频一区二区三区| 久久99精品久久久久久野外| 亚洲欧美另类在线观看| 少妇人妻一区二区| 欧美一级欧美三级在线观看| 中文字幕久久网| 欧美日韩中文字幕综合视频| 欧美日韩精品在线观看视频 | 国精产品一区一区三区四川| 久久免费在线观看| 污污的网站在线免费观看| 最近2019年中文视频免费在线观看 | 在线免费观看日本欧美爱情大片| 国内视频一区| jazzjazz国产精品久久| 91综合免费在线| 欧美伊人亚洲伊人色综合动图| 日本老师69xxx| 美女91在线看| 久久久久亚洲精品| 欧美日韩色网| 欧美成人精品一区| 在线播放免费av| 欧美成人免费全部| av免费在线免费| 美日韩在线视频| gogogogo高清视频在线| 理论片在线不卡免费观看| 蜜桃视频网站在线观看| 精品国产一区二区三区在线观看 | www.黄色网| 国产一区二区三区精品欧美日韩一区二区三区 | 麻豆av免费看| 国产一区高清在线| www.五月天色| 精品无码三级在线观看视频| 亚洲精品久久久久久宅男| 毛片一区二区三区| 最新国产黄色网址| 国产米奇在线777精品观看| 四虎1515hh.com| 成人在线综合网| 91黄色免费视频| 91美女福利视频| 欧洲av一区二区三区| 国产亚洲精品福利| 女性裸体视频网站| 亚洲欧洲综合另类在线 | 丁香五六月婷婷久久激情| 你懂的国产在线| 欧美这里有精品| 一级黄色片免费看| 日韩女优av电影在线观看| 嫩草影院一区二区| 亚洲免费中文字幕| wwwww在线观看免费视频| 日韩在线视频国产| 永久免费网站在线| 91大神福利视频在线| 99re66热这里只有精品4| 91久久精品美女高潮| 大奶在线精品| 日韩精品一区二区三区四区五区 | www.国产免费| 日韩精品中文字幕视频在线| 风间由美一区| 欧美激情精品久久久久久| 忘忧草在线日韩www影院| 国产精品永久免费观看| 伊人www22综合色| 欧美日韩在线播放一区二区| 香蕉精品视频在线观看| 日日摸日日碰夜夜爽无码| 日韩电影免费在线观看网站| 免费不卡av网站| 久久久一区二区三区| h色网站在线观看| 欧美日韩在线影院| av中文字幕播放| 亚洲欧美中文日韩v在线观看| 免费在线视频欧美| 午夜精品久久久久久99热| 国产激情欧美| 国产一区高清视频| 五月天久久网站| 国产又黄又大又粗视频| 国产精品一区2区| av男人的天堂av| 亚洲一级二级三级在线免费观看| 国产免费www| 精品国产1区二区| 日本三级在线播放完整版| 97精品视频在线播放| 欧州一区二区三区| 日韩少妇中文字幕| 日韩午夜免费| 91精品国产高清91久久久久久| 国产精品污网站| 国产精品视频免费播放| 日韩精品专区在线影院观看| av电影在线观看网址| 热久久免费视频精品| 国产精品45p| 成年人视频大全| 奇米精品一区二区三区四区 | 免费欧美激情| 蜜臀av色欲a片无码精品一区 | 超碰porn在线| 国产精品人成电影在线观看| 亚洲精品合集| 男人插女人视频在线观看| 国产精品一区二区三区99 | 亚洲高清一区二区三区| 国产精品探花视频| 中文字幕日韩精品在线| 欧美成人黑人| 看高清中日韩色视频| 伊人影院久久| 久久久男人的天堂| 亚洲综合免费观看高清完整版 | 国产超碰在线一区| www.超碰在线观看| 337p亚洲精品色噜噜狠狠| 1769在线观看| 国产欧美精品va在线观看| 欧美日韩国产传媒| 亚洲精品高清无码视频| 久久亚洲免费视频| 99超碰在线观看| 亚洲欧美一区二区三区久久| 亚洲精品国产精品国产| 欧美日韩一区在线视频| 日韩中文字幕一区二区三区| 国产交换配乱淫视频免费| 在线免费观看不卡av| 国产对白叫床清晰在线播放| 国产精品麻豆va在线播放| 欧美日韩激情在线一区二区三区| www日韩在线观看| 国产精品丝袜黑色高跟| 亚洲视频在线观看一区二区| 久久激情视频免费观看| 99tv成人影院| 国产a级黄色大片| 成人听书哪个软件好| 日韩欧美不卡视频| 亚洲区免费影片| 成人av集中营| 女人床在线观看| av电影在线观看完整版一区二区| 精品欧美一区二区三区免费观看| 亚洲欧美日韩天堂| 欧美天堂在线| 久久久久福利视频| 成年人午夜久久久| 天天干天天色综合| 综合国产在线观看| 亚洲精品午夜| 北条麻妃69av| 国产精品美女久久久久aⅴ| 99热精品在线播放| 91干在线观看| 人人狠狠综合久久亚洲婷| 一级黄色免费毛片| 精品高清一区二区三区| 北岛玲一区二区三区| 91网站在线免费观看| 亚洲巨乳在线| 国产一级淫片久久久片a级| 精品久久久三级丝袜| 久久电影tv| 国产91porn| 久久影音资源网| 国产成人麻豆精品午夜在线 | 国产激情综合| 欧美精品99久久| 综合激情成人伊人| 色网站免费观看| 国产精品一区av| 亚洲日本视频| 国产精品免费人成网站酒店| 欧美精品一区二区三区一线天视频| 欧美大片高清| 日韩一级特黄毛片| 国产日韩影视精品| 老牛影视av牛牛影视av| 国产精品一区二区久久久久| 亚洲国内自拍| 免费一级黄色大片| 最近日韩中文字幕中文|