Android8.0(API26)之Activity启动流程(显示启动)

Posted 不一样的农民

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android8.0(API26)之Activity启动流程(显示启动)相关的知识,希望对你有一定的参考价值。

 

 

我们自己的启动Activity方法

调用Activity对象的方法

@Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

继续调用Activity对象方法

@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

继续调用Activity对象方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

继续调用Activity对象方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {//mParent指的是ActivityGroup,可以在一个界面里嵌套多个Activity。随着版本的升级,在API13以后就废弃掉了。
            options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar
= mInstrumentation.execStartActivity(//调用了方法Instrumentation$execStartActivity,因为mParent为null。 this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult(//mMainThread是一个ActivityThread对象,该对象初始化在当前Activity的attach方法中。 mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } if (requestCode >= 0) { // If this start is requesting a result, we can avoid making // the activity visible until the result is received. Setting // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the // activity hidden during this time, to avoid flickering. // This can only be done when a result is requested because // that guarantees we will get information back when the // activity is finished, no matter what happens to it. mStartedActivity = true; } cancelInputsAndStartExitTransition(options); // TODO Consider clearing/flushing other event sources and events for child windows. } else { if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { // Note we want to go through this method for compatibility with // existing applications that may have overridden it. mParent.startActivityFromChild(this, intent, requestCode); } } }

在startActivityForResult这个方法中 我们发现如果

requestCode > 0会把标志位mStartedActivity改成true(这个关于)
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

这个方法是否回调。

在回头查看启动的重点:根据上面的注释我们继续查看Instrumentation的execStartActivity方法

 1     public void execStartActivitiesAsUser(Context who, IBinder contextThread,
 2             IBinder token, Activity target, Intent[] intents, Bundle options,
 3             int userId) {
 4         IApplicationThread whoThread = (IApplicationThread) contextThread;//ActivityThread的ApplictionThread对象
 5         if (mActivityMonitors != null) {
 6             synchronized (mSync) {
 7                 final int N = mActivityMonitors.size();
 8                 for (int i=0; i<N; i++) {
 9                     final ActivityMonitor am = mActivityMonitors.get(i);//List<ActivityMonitor> mActivityMonitors
10                     ActivityResult result = null;
11                     if (am.ignoreMatchingSpecificIntents()) {
12                         result = am.onStartActivity(intents[0]);//这个方法返回的是null
13                     }
14                     if (result != null) {
15                         am.mHits++;
16                         return;
17                     } else if (am.match(who, null, intents[0])) {//用于拦截任何已启动的活动
18                         am.mHits++;
19                         if (am.isBlocking()) {
20                             return;
21                         }
22                         break;
23                     }
24                 }
25             }
26         }
27         try {
28             String[] resolvedTypes = new String[intents.length];
29             for (int i=0; i<intents.length; i++) {
30                 intents[i].migrateExtraStreamToClipData();
31                 intents[i].prepareToLeaveProcess(who);
32                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
33             }
34             int result = ActivityManager.getService()
35                 .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,
36                         token, options, userId);
37             checkStartActivityResult(result, intents[0]);
38         } catch (RemoteException e) {
39             throw new RuntimeException("Failure from system", e);
40         }
41     }
第4行代码:private class ApplicationThread extends IApplicationThread.Stub{}是在ActivityThread中ApplictionThread的构造方法、
通过代码分析(有注释)可知这里的重点事:

 

我们再来查看ActivityManager.getService()方法返回的对象:

 1    public static IActivityManager getService() {
 2         return IActivityManagerSingleton.get();
 3     }
 4 
 5     private static final Singleton<IActivityManager> IActivityManagerSingleton =
 6             new Singleton<IActivityManager>() {
 7                 @Override
 8                 protected IActivityManager create() {
 9                     final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
10                     final IActivityManager am = IActivityManager.Stub.asInterface(b);
11                     return am;
12                 }
13             };

 

返回的对象是一个IActivityManager,其中Singleton<T>是创建一个T的单列对象通过get()方法获取T对象。所以这里获取的是一个IActivityManager对象

这里的大概意思就是基于(Bidler机制)获取ActivityManagerServer在应用进程的代理对象IActivityManager(这里需要了解Binder机制,会另外写bidler机制)

所以这里的Instrumentation中的getMananger.getServer.startActivity 等价于--IActivityManager.startActivity----等价于ActivityManagerServer.startActivity方法。

 

继续查看ActivityManagerServer对象的startActivity方法:

 1     /**
 2      * Instrumentaion 调用的是这个方法
 3      * @return 返回值用于判断Activity是否启动
 4      */
 5     @Override
 6     public final int startActivity(IApplicationThread caller, String callingPackage,
 7             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
 8             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
 9         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
10                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
11                 UserHandle.getCallingUserId());
12     }

继续查看startActivityAsUer方法

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        //获取userid
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO:  在这里切换到用户应用程序栈。(Switch to user app stacks here.)
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null,
                "startActivityAsUser");
    }

  继续查看mActivityStarter.startActivityMayWait方法,mActivityStarter是ActivityStarter对象

  1     final int startActivityMayWait(IApplicationThread caller, int callingUid,
  2             String callingPackage, Intent intent, String resolvedType,
  3             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
  4             IBinder resultTo, String resultWho, int requestCode, int startFlags,
  5             ProfilerInfo profilerInfo, WaitResult outResult,
  6             Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
  7             IActivityContainer iContainer, TaskRecord inTask, String reason) {
  8         // Refuse possible leaked file descriptors
  9         if (intent != null && intent.hasFileDescriptors()) {
 10             throw new IllegalArgumentException("File descriptors passed in Intent");
 11         }
 12         //调用底层的方法 给ActivityMetricsLogger的INVALID_START_TIME赋值
 13         mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
 14         boolean componentSpecified = intent.getComponent() != null;//显示启动为true
 15 
 16         // Save a copy in case ephemeral needs it
 17         final Intent ephemeralIntent = new Intent(intent);
 18         // Don\'t modify the client\'s object!
 19         //为了不改变用户的intent
 20         intent = new Intent(intent);
 21         if (componentSpecified
 22                 && intent.getData() != null
 23                 && Intent.ACTION_VIEW.equals(intent.getAction())
 24                 && mService.getPackageManagerInternalLocked()
 25                         .isInstantAppInstallerComponent(intent.getComponent())) {//判断是否调用系统功能
 26             // intercept intents targeted directly to the ephemeral installer the
 27             // ephemeral installer should never be started with a raw URL; instead
 28             // adjust the intent so it looks like a "normal" instant app launch
 29             intent.setComponent(null /*component*/);
 30             componentSpecified = false;
 31         }
 32         //收集Intent所指向的Activity信息, 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity
 33         ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
 34         if (rInfo == null) {
 35             UserInfo userInfo = mSupervisor.getUserInfo(userId);//UserInfo 保存了应用相关信息 名字 图片....
 36             if (userInfo != null && userInfo.isManagedProfile()) {//不会执行(估计)
 37                 // Special case for managed profiles, if attempting to launch non-cryto aware
 38                 // app in a locked managed profile from an unlocked parent allow it to resolve
 39                 // as user will be sent via confirm credentials to unlock the profile.
 40                 UserManager userManager = UserManager.get(mService.mContext);
 41                 boolean profileLockedAndParentUnlockingOrUnlocked = false;
 42                 long token = Binder.clearCallingIdentity();
 43                 try {
 44                     UserInfo parent = userManager.getProfileParent(userId);
 45                     profileLockedAndParentUnlockingOrUnlocked = (parent != null)
 46                             && userManager.isUserUnlockingOrUnlocked(parent.id)
 47                             && !userManager.isUserUnlockingOrUnlocked(userId);
 48                 } finally {
 49                     Binder.restoreCallingIdentity(token);
 50                 }
 51                 if (profileLockedAndParentUnlockingOrUnlocked) {
 52                     rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
 53                             PackageManager.MATCH_DIRECT_BOOT_AWARE
 54                                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
 55                 }
 56             }
 57         }
 58         // 收集有关目标的信息。(Collect information about the target of the Intent.)
 59         //收集目标intent的信息,在resolveActivity方法中与PKMS交互获得
 60         //该过程主要功能:通过resolveActivity来获取ActivityInfo信息, 找到相应的Activity组件,并保存到intent对象,然后再进入startActivityLocked()
 61         ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
 62 
 63         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
 64         ActivityStackSupervisor.ActivityContainer container =
 65                 (ActivityStackSupervisor.ActivityContainer)iContainer;
 66         synchronized (mService) {
 67             if (container != null && container.mParentActivity != null &&
 68                     container.mParentActivity.state != RESUMED) {
 69                 // Cannot start a child activity if the parent is not resumed.
 70                 return ActivityManager.START_CANCELED;
 71             }
 72             final int realCallingPid = Binder.getCallingPid();
 73             final int realCallingUid = Binder.getCallingUid();
 74             int callingPid;
 75             if (callingUid >= 0) {
 76                 callingPid = -1;
 77             } else if (caller == null) {
 78                 callingPid = realCallingPid;
 79                 callingUid = realCallingUid;
 80             } else {
 81                 callingPid = callingUid = -1;
 82             }
 83 
 84             final ActivityStack stack;
 85             //取得需要启动的ActivityStack栈
 86             if (container == null || container.mStack.isOnHomeDisplay()) {
 87                 stack = mSupervisor.mFocusedStack;
 88             } else {
 89                 stack = container.mStack;
 90             }
 91             stack.mConfigWillChange = globalConfig != null
 92                     && mService.getGlobalConfiguration().diff(globalConfig) != 0;
 93             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
 94                     "Starting activity when config will change = " + stack.mConfigWillChange);
 95 
 96             final long origId = Binder.clearCallingIdentity();
 97 
 98             if (aInfo != null &&
 99                     (aInfo.applicationInfo.privateFlags
100                             & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
101                 // This may be a heavy-weight process!  Check to see if we already
102                 // have another, different heavy-weight process running.
103                 //androidmanifest.xml中的Application标签可以声明一个cantSaveState属性,若设置,其将不享受系统提
104                 //供的状态保存/恢复功能。主要是为了保证用户体验的连续性
105                 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
106                     final ProcessRecord heavy = mService.mHeavyWeightProcess;
107                     if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
108                             || !heavy.processName.equals(aInfo.processName))) {
109                         int appCallingUid = callingUid;
110                         if (caller != null) {
111                             ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
112                             if (callerApp != null) {
113                                 appCallingUid = callerApp.info.uid;
114                             } else {
115                                 Slog.w(TAG, "Unable to find app for caller " + caller
116                                         + " (pid=" + callingPid + ") when starting: "
117                                         + intent.toString());
118                                 ActivityOptions.abort(options);
119                                 return ActivityManager.START_PERMISSION_DENIED;
120                             }
121                         }
122 
123                         IIntentSender target = mService.getIntentSenderLocked(
124                                 ActivityManager.INTENT_SENDER_ACTIVITY, "android",
125                                 appCallingUid, userId, null, null, 0, new Intent[] { intent },
126                                 new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
127                                         | PendingIntent.FLAG_ONE_SHOT, null);
128 
129                         Intent newIntent = new Intent();
130                         if (requestCode >= 0) {
131                             // Caller is requesting a result.
132                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
133                         }
134                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
135                                 new IntentSender(target));
136                         if (heavy.activities.size() > 0) {
137                             ActivityRecord hist = heavy.activities.get(0);
138                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
139                                     hist.packageName);
140                             newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
141                                     hist.getTask().taskId);
142                         }
143                         newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
144                                 aInfo.packageName);
145                         newIntent.setFlags(intent.getFlags());
146                         newIntent.setClassName("android",
147                                 HeavyWeightSwitcherActivity.class.getName());
148                         intent = newIntent;
149                         resolvedType = null;
150                         caller = null;
151                         callingUid = Binder.getCallingUid();
152                         callingPid = Binder.getCallingPid();
153                         componentSpecified = true;
154                         rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
155                         aInfo = rInfo != null ? rInfo.activityInfo : null;
156                         if (aInfo != null) {
157                             aInfo = mService.getActivityInfoForUser(aInfo, userId);
158                         }
159                     }
160                 }
161             }
162             final ActivityRecord[] outRecord = new ActivityRecord[1];
163             //启动Activity
164             int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
165                     aInfo, rInfo, voiceSession, voiceInteractor,
166                     resultTo, resultWho, requestCode, callingPid,
167                     callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
168                     options, ignoreTargetSecurity, componentSpecified, outRecord, container,
169                     inTask, reason);
170 
171             Binder.restoreCallingIdentity(origId);
172             //如果配置Configration发生变化,则调用AMS的updateConfigurationLocked进行处理
173             if (stack.mConfigWillChange) {
174                 // If the caller also wants to switch to a new configuration,
175                 // do so now.  This allows a clean switch, as we are waiting
176                 // for the current activity to pause (so we will not destroy
177                 // it), and have not yet started the next activity.
178                 //如果调用方也希望切换到新配置
179                 //现在就这样做。这允许一个干净的开关,因为我们正在等待
180                 //为当前活动暂停(因此我们不会破坏)
181                 //它还没有启动下一个活动。
182                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
183                         "updateConfiguration()");
184                 stack.mConfigWillChange = false;
185                 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
186                         "Updating to new configuration after starting activity.");
187                 mService.updateConfigurationLocked(globalConfig, null, false);
188             }
189 
190             if (outResult != null) {
191                 outResult.result = res;
192                 if (res == ActivityManager.START_SUCCESS) {
193                     //将结果放入mWaitingActivityLaunced中保存
194                     mSupervisor.mWaitingActivityLaunched.add(outResult);
195                     do {
196                         try {
197                             //等待启动结果
198                             mService.wait();
199                         } catch (InterruptedException e) {
200                         }
201                     } while (outResult.result != START_TASK_TO_FRONT
202                             && !outResult.timeout && outResult.who == null);
203                     if (outResult.result == START_TASK_TO_FRONT) {
204                         res = START_TASK_TO_FRONT;
205                     }
206                 }
207                 if (res == START_TASK_TO_FRONT) {
208                     final ActivityRecord r = outRecord[0];
209 
210                     // ActivityRecord may represent a different activity, but it should not be in
211                     // the resumed state.
212                     if (r.nowVisible && r.state == RESUMED) {
213                         outResult.timeout = false;
214                         outResult.who = r.realActivity;
215                         outResult.totalTime = 0;
216                         outResult.thisTime = 0;
217                     } else {
218                         outResult.thisTime = SystemClock.uptimeMillis();
219                         mSupervisor.waitActivityVisible(r.realActivity, outResult);
220                         // Note: the timeout variable is not currently not ever set.
221                  

以上是关于Android8.0(API26)之Activity启动流程(显示启动)的主要内容,如果未能解决你的问题,请参考以下文章

Android PlayStore警告您的应用目前的目标是API级别25

Android 版本API对应表

Android 版本API对应表

Android 版本API对应表

Android8.0适配那点事

Android系统版本特性(4.4版本--11版本)