图解Activity启动流程

前言

  • 基于android4.4.2源码
  • activity 生命周期图

    本文在讲诉Activity启动流程涉及到了一些Activity生命周期的知识,所以把官方文档直接贴上来(附图1),对Activity生命周期知识了然于心的大神直接无视就好。对于刚接触android的看客,则需要先去了解这方面的知识。

  • 涉及知识

    binder机制,因本人原因只能在后续的文章才会更新这方面的内容,对这方面不了解的看客建议先去看binder机制的知识。

    android Task ,官方文档解释很清楚。

附图1

  

一、Activity启动流程

(一)在Launch发送startActivity请求

  在我们的Android系统中,应用程序是由Launch这个应用启动起来的。当我们安装好应用程序之后,就会在Launch的界面上生成一个图标,我们点击图标时Launch就会启动我们的应用程序。这一过程会去收集我们应用程序一些相关的信息然后通过IPC通信送到AMS。这第一大步的流程如图1所示:

图1

 

  1. AppsCustomizePagedView.onClick

 1 public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
 2         View.OnClickListener, View.OnKeyListener, DragSource,
 3         PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener,
 4         LauncherTransitionable {
 5         
 6     //当在屏幕上点击app图标,就会调用AppsCustomizePagedView类的成员函数onClick
 7     //主要获得app的一些相关信息然后就调用Launcher这个类的成员函数startActivitySafely
 8     public void onClick(View v) {
 9         
10         if (v instanceof PagedViewIcon) {
11             // Animate some feedback to the click
12             final ApplicationInfo appInfo = (ApplicationInfo) v.getTag();
13 
14             // Lock the drawable state to pressed until we return to Launcher
15             if (mPressedIcon != null) {
16             mPressedIcon.lockDrawableState();
17             }
18           
19             mLauncher.updateWallpaperVisibility(true);                   
20             mLauncher.startActivitySafely(v, appInfo.intent, appInfo);   // goto step 2--->
21         } else if (v instanceof PagedViewWidget) {
22            //code....
23         }
24     }
25 }

 

  2. Launcher.startActivitySafely

 1 public final class Launcher extends Activity
 2         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
 3                    View.OnTouchListener {
 4     //这个函数主要是用来把应用程序里面的AndroidManifest.xml文件中的一些配置信息保存到intent里
 5     boolean startActivitySafely(View v, Intent intent, Object tag) {            
 6         boolean success = false;
 7         try {
 8             /* intent包含的信息为 : 
 9              * action = "android.intent.action.Main",
10              * category="android.intent.category.LAUNCHER", 
11              * cmp="com.activity/.MainActivity" <---要启动的Activity
12              */
13             success = startActivity(v, intent, tag);  //  goto step 3 --->
14         } catch (ActivityNotFoundException e) {
15             //code...
16         }
17         return success;
18     }
19 }    

 

  3. Launcher.startActivity

 1 public final class Launcher extends Activity
 2         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
 3                    View.OnTouchListener {
 4     //这个函数主要是获得高和宽,然后调用Activity类的成员函数startActivity
 5     //因为Launcher继承于Activity类,而Activity类实现了startActivity函数
 6     boolean startActivity(View v, Intent intent, Object tag) {                   
 7         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 8         try {
 9             boolean useLaunchAnimation = (v != null) &&
10                 !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION); // useLaunchAnimation = true
11             if (useLaunchAnimation) { //come here
12             ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
13                 v.getMeasuredWidth(), v.getMeasuredHeight());
14 
15             startActivity(intent, opts.toBundle());  //  goto step 4 --->
16             } else {            
17             startActivity(intent);
18             }
19             return true;
20         } catch (SecurityException e) {
21            //code...
22         }
23         return false;
24     }                           
25 }

 

   4. Activity.startActivity

 1 public class Activity extends ContextThemeWrapper
 2         implements LayoutInflater.Factory2,
 3         Window.Callback, KeyEvent.Callback,
 4         OnCreateContextMenuListener, ComponentCallbacks2 {
 5         
 6     //不做实事的函数,只是单纯的调用startActivityForResult函数而已
 7     public void startActivity(Intent intent, Bundle options) {
 8         if (options != null) {      //come here 
 9             startActivityForResult(intent, -1, options);  //  goto step 5 --->
10         } else {            
11             startActivityForResult(intent, -1);
12         }
13     }
14 }

 

  5. Activity.startActivityForResult

 1 public class Activity extends ContextThemeWrapper
 2         implements LayoutInflater.Factory2,
 3         Window.Callback, KeyEvent.Callback,
 4         OnCreateContextMenuListener, ComponentCallbacks2 {
 5             
 6     public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
 7         //根据传进来的参数,就可以把这个函数无关代码省略
 8         //intent : pos ...
 9         //requestCode = -1
10         //options : app name ...
11         
12         if (mParent == null) {
13             /*
14              * 1. mMainThread的类型为ActivityThread,同时也是Activity类的一个变量
15              *     mMainThread.getApplicationThread() 获得ApplicationThread成员变量,即一个Binder对象
16              *    注 : mMainThread代表的是Launcher应用程序运行的进程
17              * 2. mToken : Activity类的一个变量,是一个Binder对象的远程接口
18              */
19             Instrumentation.ActivityResult ar =
20             mInstrumentation.execStartActivity(   //  goto step 6   --->
21                 this, mMainThread.getApplicationThread(), mToken, this,
22                 intent, requestCode, options);
23             //code...
24         } else {
25            //code...
26         }
27     }
28 }

 

  6.  Instrumentation.execStartActivity

 1 public class Instrumentation {
 2 
 3     //这个函数也可以说不做实事,只是通过IPC通信而已
 4     public ActivityResult execStartActivity(
 5             Context who, IBinder contextThread, IBinder token, Activity target,
 6             Intent intent, int requestCode, Bundle options) {
 7         IApplicationThread whoThread = (IApplicationThread) contextThread;
 8         if (mActivityMonitors != null) {
 9            //code...
10         }
11         try {
12     
13             intent.migrateExtraStreamToClipData();
14             intent.prepareToLeaveProcess();
15         
16         //ActivityManagerNative.getDefault返回ActivityManagerService的远程接口,即ActivityManagerProxy接口
17         //target != null 
18         //target.mEmbddedID = null
19             int result = ActivityManagerNative.getDefault()                //  goto step 7  --->
20                 .startActivity(whoThread, who.getBasePackageName(), intent,
21                         intent.resolveTypeIfNeeded(who.getContentResolver()),
22                         token, target != null ? target.mEmbeddedID : null,
23                         requestCode, 0, null, null, options);
24             checkStartActivityResult(result, intent);
25         } catch (RemoteException e) {
26         }
27         return null;
28  }

 

(二)AMS接收客户端startActivity请求

  AMS接收到Launcher请求Activity后,就对这个将要启动的Activity进行一些相关信息的的解析及检查,然后创建一个ActivityRecord。其流程如图2所示:  

 

图2

  7. ActivityManagerProxy.startActivity

 1 class ActivityManagerProxy implements IActivityManager
 2 {
 3     /* 没什么好说的,就是把信息转发到AMS里而已 
 4      * 1. caller : ApplicationThread类型的Binder实体
 5      * 2. resultTo : 为一个Binder实体的远程接口
 6      * 3. resolvedType = grantedUriPermissions = resultWho = null
 7      * 4. grantedMode = 0 requestCode = -1 onlyIfNeeded = debug = false
 8      */    
 9     public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
10             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
11             int startFlags, String profileFile,
12             ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
13         Parcel data = Parcel.obtain();
14         Parcel reply = Parcel.obtain();
15         data.writeInterfaceToken(IActivityManager.descriptor);
16         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
17         data.writeString(callingPackage);
18         intent.writeToParcel(data, 0);
19         data.writeString(resolvedType);
20         data.writeStrongBinder(resultTo);
21         data.writeString(resultWho);
22         data.writeInt(requestCode);
23         data.writeInt(startFlags);
24         data.writeString(profileFile);
25         if (profileFd != null) {
26             data.writeInt(1);
27             profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
28         } else {
29             data.writeInt(0);
30         }
31         if (options != null) {
32             data.writeInt(1);
33             options.writeToParcel(data, 0);
34         } else {
35             data.writeInt(0);
36         }
37         mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
38         reply.readException();
39         int result = reply.readInt();
40         reply.recycle();
41         data.recycle();
42         return result;
43     }
44 }

 

  8. ActivityManagerService.startActivity

 1 public final class ActivityManagerService extends ActivityManagerNative
 2         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 3     //不干实事的函数,就是单纯的调用ActivityManagerService.startActivityAsUser
 4     public final int startActivity(IApplicationThread caller, String callingPackage,
 5             Intent intent, String resolvedType, IBinder resultTo,
 6             String resultWho, int requestCode, int startFlags,
 7             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
 8         //  goto step 9  --->
 9         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
10             resultWho, requestCode,
11             startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
12     }          
13 }

 

  9. ActivityManagerService.startActivityAsUser

 1 public final class ActivityManagerService extends ActivityManagerNative
 2         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 3     //也是基本都做事,只是单纯的调用ActivityStackSupervisor.startActivityMayWait
 4     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
 5             Intent intent, String resolvedType, IBinder resultTo,
 6             String resultWho, int requestCode, int startFlags,
 7             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
 8         
 9         enforceNotIsolatedCaller("startActivity");
10         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
11             false, true, "startActivity", null);
12 
13         //  goto step 10  --->
14         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
15             resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
16             null, null, options, userId);
17     }
18 } 

 

  10. ActivityStackSupervisor.startActivityMayWait

 1 public final class ActivityStackSupervisor {
 2 
 3     //对intent的内容进行解析,得到MainActivity的相关信息后,把其保存在aInfo
 4     final int startActivityMayWait(IApplicationThread caller, int callingUid,
 5             String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
 6             String resultWho, int requestCode, int startFlags, String profileFile,
 7             ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
 8             Bundle options, int userId) {
 9         
10         //执行完后 componentSpecified = true
11         boolean componentSpecified = intent.getComponent() != null;
12 
13         // Don't modify the client's object!
14         intent = new Intent(intent);
15             
16         //对参数intent的内容进行解析      
17         ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
18                 profileFile, profileFd, userId);
19 
20         synchronized (mService) {
21             int callingPid;
22             if (callingUid >= 0) {
23                 //code...
24             } else if (caller == null) {
25                //code...
26             } else {
27                 callingPid = callingUid = -1;
28             }
29 
30             final ActivityStack stack = getFocusedStack();
31             stack.mConfigWillChange = config != null
32                     && mService.mConfiguration.diff(config) != 0;
33            
34             final long origId = Binder.clearCallingIdentity();
35 
36             if (aInfo != null &&
37                     (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
38 
39                   //code...这里有一大段if语句的代码,先把他省略掉
40             }        
41         
42             //  goto step 11 --->
43             int res = startActivityLocked(caller, intent, resolvedType,
44                     aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
45                     callingPackage, startFlags, options, componentSpecified, null);
46 
47             if (stack.mConfigWillChange) {            
48                 mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
49                         "updateConfiguration()");
50                 stack.mConfigWillChange = false;
51                 if (DEBUG_CONFIGURATION) Slog.v(TAG,
52                         "Updating to new configuration after starting activity.");
53                 mService.updateConfigurationLocked(config, null, false, false);
54             }
55 
56             Binder.restoreCallingIdentity(origId);
57 
58             if (outResult != null) { //outResult = null 
59                 outResult.result = res;
60                 if (res == ActivityManager.START_SUCCESS) {
61                     mWaitingActivityLaunched.add(outResult);
62                     do {
63                         try {
64                             mService.wait();
65                         } catch (InterruptedException e) {
66                         }
67                     } while (!outResult.timeout && outResult.who == null);
68                 } else if (res == ActivityManager.START_TASK_TO_FRONT) {
69                     ActivityRecord r = stack.topRunningActivityLocked(null);
70                     if (r.nowVisible) {
71                         outResult.timeout = false;
72                         outResult.who = new ComponentName(r.info.packageName, r.info.name);
73                         outResult.totalTime = 0;
74                         outResult.thisTime = 0;
75                     } else {
76                         outResult.thisTime = SystemClock.uptimeMillis();
77                         mWaitingActivityVisible.add(outResult);
78                         do {
79                             try {
80                                 mService.wait();
81                             } catch (InterruptedException e) {
82                             }
83                         } while (!outResult.timeout && outResult.who == null);
84                     }
85                 }
86             }
87 
88             return res;
89         }
90     }
91 
92 }

 

  11. ActivityStackSupervisor.startActivityLocked

  1 public final class ActivityStackSupervisor {
  2     //主要是保存Launcher的相关信息及创建一个ActivityRecord
  3     //代码中会有一些详细的注释
  4     final int startActivityLocked(IApplicationThread caller,
  5             Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
  6             String resultWho, int requestCode,
  7             int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
  8             boolean componentSpecified, ActivityRecord[] outActivity) {
  9         int err = ActivityManager.START_SUCCESS;
 10 
 11         ProcessRecord callerApp = null;
 12         if (caller != null) {
 13             //获取Launch的相关信息(pid,uid)保存到ProcessRecord变量
 14             callerApp = mService.getRecordForAppLocked(caller);
 15             if (callerApp != null) {
 16                 callingPid = callerApp.pid;
 17                 callingUid = callerApp.info.uid;
 18             } else {
 19                //code...
 20             }
 21         }
 22 
 23         if (err == ActivityManager.START_SUCCESS) {
 24             final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;           
 25         }
 26 
 27         ActivityRecord sourceRecord = null;  //表示正在执行的Activity(在当前的情景下也就是Launcher)
 28         ActivityRecord resultRecord = null;  //表示启动将要启动的Activity返回的结果,(在当前的情景下将要启动的Activity就是MainActivity)
 29         if (resultTo != null) {
 30             //获得Launcher的相关信息保存在ActivityRecord里
 31             sourceRecord = isInAnyStackLocked(resultTo);
 32                        
 33             if (sourceRecord != null) {
 34                 if (requestCode >= 0 && !sourceRecord.finishing) {
 35                     //code...
 36                 }
 37             }
 38         }
 39         
 40         ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
 41 
 42         int launchFlags = intent.getFlags();
 43 
 44         if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
 45                 && sourceRecord != null) {
 46             //code...
 47         }
 48 
 49         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
 50            //code..
 51         }
 52 
 53         if (err == ActivityManager.START_SUCCESS && aInfo == null) {
 54            //code...
 55         }
 56 
 57         if (err != ActivityManager.START_SUCCESS) {
 58             //code...
 59         }
 60 
 61         //以下一代段代码主要是对Activity进行一序列权限的检查
 62         final int startAnyPerm = mService.checkPermission(
 63                 START_ANY_ACTIVITY, callingPid, callingUid);
 64         final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
 65                 callingUid, aInfo.applicationInfo.uid, aInfo.exported);
 66         if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
 67             if (resultRecord != null) {
 68                 resultStack.sendActivityResultLocked(-1,
 69                     resultRecord, resultWho, requestCode,
 70                     Activity.RESULT_CANCELED, null);
 71             }
 72             setDismissKeyguard(false);
 73             String msg;
 74             if (!aInfo.exported) {
 75                 msg = "Permission Denial: starting " + intent.toString()
 76                         + " from " + callerApp + " (pid=" + callingPid
 77                         + ", uid=" + callingUid + ")"
 78                         + " not exported from uid " + aInfo.applicationInfo.uid;
 79             } else {
 80                 msg = "Permission Denial: starting " + intent.toString()
 81                         + " from " + callerApp + " (pid=" + callingPid
 82                         + ", uid=" + callingUid + ")"
 83                         + " requires " + aInfo.permission;
 84             }
 85             Slog.w(TAG, msg);
 86             throw new SecurityException(msg);
 87         }
 88 
 89         boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
 90                 callingPid, resolvedType, aInfo.applicationInfo);
 91 
 92         if (mService.mController != null) {
 93             try {
 94                 // The Intent we give to the watcher has the extra data
 95                 // stripped off, since it can contain private information.
 96                 Intent watchIntent = intent.cloneFilter();
 97                 abort |= !mService.mController.activityStarting(watchIntent,
 98                         aInfo.applicationInfo.packageName);
 99             } catch (RemoteException e) {
100                 mService.mController = null;
101             }
102         }
103 
104         if (abort) {
105             if (resultRecord != null) {
106                 resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
107                         Activity.RESULT_CANCELED, null);
108             }
109             // We pretend to the caller that it was really started, but
110             // they will just get a cancel result.
111             setDismissKeyguard(false);
112             ActivityOptions.abort(options);
113             return ActivityManager.START_SUCCESS;
114         }
115 
116         //创建一个 ActivityRecord , 包括uid,packagename,intent,ainfo,requestCode等等信息
117         ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
118                 intent, resolvedType, aInfo, mService.mConfiguration,
119                 resultRecord, resultWho, requestCode, componentSpecified, this);    
120         
121         if (outActivity != null) {
122             outActivity[0] = r;
123         }
124 
125         final ActivityStack stack = getFocusedStack();
126         if (stack.mResumedActivity == null
127                 || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
128             if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
129                 PendingActivityLaunch pal =
130                         new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
131                 mService.mPendingActivityLaunches.add(pal);
132                 setDismissKeyguard(false);
133                 ActivityOptions.abort(options);
134                 return ActivityManager.START_SWITCHES_CANCELED;
135             }
136         }
137 
138         if (mService.mDidAppSwitch) {
139             // This is the second allowed switch since we stopped switches,
140             // so now just generally allow switches.  Use case: user presses
141             // home (switches disabled, switch to home, mDidAppSwitch now true);
142             // user taps a home icon (coming from home so allowed, we hit here
143             // and now allow anyone to switch again).
144             mService.mAppSwitchesAllowedTime = 0;
145         } else {
146             mService.mDidAppSwitch = true;
147         }
148 
149         mService.doPendingActivityLaunchesLocked(false);
150 
151         //  goto step 12   --->
152         err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
153 
154         if (allPausedActivitiesComplete()) {           
155             dismissKeyguard();
156         }
157         return err;
158     }
159 }

 

(三)创建新的Task

  明天再更新。。。。

 

 

 

 

 

 

 

 

 

 

 

 

 

二、小结

  • ActivityThread  

     ActivityThread类有一个main方法,它是应用程序的入口,每启动一个应用进程,都会创建ActivityThread与之对应的实例,是应用程序的UI线程,Android进程启动时会建立消息循环(前文图解中也有说明)。

  • ApplicationThread & ApplicatinThreadNative

    ApplicationThread用来实现AMS(ActivityManagerService)与AT(ActivityThread)之间的交互。在AMS需要管理相关Application中的Activity的生命周期时,通过ApplicationThreadAT通讯,ApplicationThreadNativeApplicationThread在客户端的实现(binder机制)。

  • ApplicationThreadProxy

    ApplicationThreadProxyApplicationThread在服务器端的代理。负责和服务器端的ApplicatingThreadNative通讯。 AMS就是通过该代理与ActivityThread进行通信的(binder机制)。

  • Activity & Intrumentation

    Activity是应用程序真正做事情的类,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用(也就是说mInstrumentation是Activity类的成员变量,前文图解中也有说明)。

    Instrumentation用来监控应用程序和系统的交互,可以理解为应用进程的管家,AT要创建或暂停某个Activity时,都需要通过Instrumentation。 通俗的理解,InstrumentationAT的区别,前者像是一个“家庭”里的“管家”,后者是负责创建这个“家庭”,并负责对外打交道,比如接收AMS的通知等。

 

后序

  本文在讲诉的过程中查阅了大量的资料,其中讲诉的一些知识难免会跟原作者“雷同”,望原作者谅解。刚接触android,文中讲诉的过程中难免会出现一些错误,希望大家能批评指正,另外后序的文章会不定时更新。

  

posted @ 2014-08-01 17:30  solo_heart  阅读(4302)  评论(0编辑  收藏  举报