那就我看code的情况,需要知道的概念有:
Tasks&Back Stack
Lifecycle
LauncherMode(standard/singleTop/singleTask/singleInstance)
File List&Class List
File List
packages/apps/Launcher2/src/com/android/launcher2/ - Launcher.java frameworks/base/core/java/android/app/ - Activity.java - Instrumentation.java - ActivityManager.java - IActivityManager.aidl - ActivityThread.java - ApplicationThread.java - H.java - IApplicationThread.aidl frameworks/base/services/core/java/com/android/server/am/ - ActivityManagerService.java - ActivityStarter.java - ActivityStackSupervisor.java - ActivityStack.java - ActivityRecord.java - ProcessRecord.java
Class List
Class | Function |
---|---|
Launcher | Default launcher application. |
Activity | Interact with the user. |
Instrumentation | Monitor all of the interaction the system has with the application. |
ActivityManager | Gives information about, and interacts with, activities, services, and the containing process. |
ActivityThread | ApplicationThread /H |
ActivityManagerService | This is a System Service |
ActivityStarter | Controller for interpreting how and then launching an activity. This class collects all the logic for determining how an intent and flags should be turned into an activity and associated task and stack. |
ActivityStackSupervisor | Supervisor of ActivityStack |
ActivityStack | State and management of a single stack of activities. |
ClientLifecycleManager | Class that is able to combine multiple client lifecycle transition requests and/or callbacks, and execute them as a single transaction. |
ClientTransaction | A container that holds a sequence of messages, which may be sent to a client. |
ClientTransactionHandler | Defines operations that a {@link android.app.servertransaction.ClientTransaction} or its items can perform on client. |
TransactionExecutor | Class that manages transaction execution in the correct order. |
Process Communication
在看函数调用之前,需要先了解process之间的关系,那这里的Launcher,system_service,Zygote,在System启动的时候就启起来了。那Launcher中是有所有App的图标,当用户点击这个图标,Launcher会告诉AMS(ActivityManagerService,在system_server进程中),我要启动一个Activity(App中android.intent.category.LAUNCHER的Activity)。但此时App还没启起来,因此,AMS通过Socket告诉Zygote去启一个process,那Zygote会fork这个App Process,最后App Process告诉AMS,process已经启起来了。
在这里插入图片描述
下面这张图是在前人的基础上稍稍改了一些,这张图也没什么好解释的,简化的Activity启动过程。
Launcher告诉ActivityManagerService,我要启动一个APP了
ActivityManagerService告诉Zygote,请求fork一个进程
fork新进程,也就是APP进程
告诉AMS,APP进程已经启动完成
告诉Binder对象去发送启动Activity的请求
向应用程序发送启动Activity的请求
向APP进程的主线程发送启动MainActivity组件的操作,LAUNCH_ACTIVITY
handleLaunchActivity
在这里插入图片描述
Activity Start Flow
那我们就照着Process中提到的顺序一步一步分析:
Launcher -> AMS
APP -> AMS
AMS -> APP
与Zygote与Process有关的这里就不分析了。
Step 1: Launcher -> AMS
首先是Launcher告诉AMS我要启动一个Activity的Flow
当用户点击App图标,会调用Launcher中startActivitySafely()
,这个函数本身没做什么事情,只是接着调用 startActivity()
,取得startActivity()
的返回值,并做异常处理,真正的逻辑在startActivity()
里。
在startActivity()
,可以看到intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
,这涉及到Activity的Task,每个Activity都有一个Task,那么启动App的时候,Activity在一个新的Task中创建。然后又调用了一个startActivity()
,这里的startActivity()
是Launcher父类,也就是Activity的startActivity()
。
/packages/apps/Launcher2/src/com/android/launcher2/Launcher.java - startActivity()
boolean startActivity(View v, Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { // Only launch using the new animation if the shortcut has not opted out (this is a // private contract between launcher and may be ignored in the future). boolean useLaunchAnimation = (v != null) && !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION); UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE); LauncherApps launcherApps = (LauncherApps) this.getSystemService(Context.LAUNCHER_APPS_SERVICE); if (useLaunchAnimation) { ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); if (user == null || user.equals(android.os.Process.myUserHandle())) { // Could be launching some bookkeeping activity startActivity(intent, opts.toBundle()); } else { launcherApps.startMainActivity(intent.getComponent(), user, intent.getSourceBounds(), opts.toBundle()); } } else { if (user == null || user.equals(android.os.Process.myUserHandle())) { startActivity(intent); } else { launcherApps.startMainActivity(intent.getComponent(), user, intent.getSourceBounds(), null); } } return true; } catch (SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Launcher does not have the permission to launch " + intent + ". Make sure to create a MAIN intent-filter for the corresponding activity " + "or use the exported attribute for this activity. " + "tag="+ tag + " intent=" + intent, e); } return false; }
/frameworks/base/core/java/android/app/Activity.java
在startActivity()
中它会,调用startActivityForResult()
/frameworks/base/core/java/android/app/Activity.java - startActivityForResult()
@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); } }
在 startActivityForResult()
中,会调用Instrumentation
的execStartActivity()
,那Instrumentation
这个类之前有介绍,是用来监控system与application之间的交互。
/frameworks/base/core/java/android/app/Activity.java - startActivityForResult()
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( 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); } } }
在execStartActivity()
里,前面有一些ActivityMonitor相关的代码,然后ActivityManager.getService() .startActivity()
,看到ActivityManager.getService()
,这里应该敏感的看出这是一个Binder对象(其实Android中很多这种IPC的套路,AccessibilityManager/LocationManager...)。你可以去看ActivityManager
看到这个函数是获取了一个IActivityManager
对象,那它其实就是AMS的Binder对象。也就是说这里其实是调用了AMS的startActivity()
函数。
/frameworks/base/core/java/android/app/Instrumentation.java - execStartActivity()
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; Uri referrer = target != null ? target.onProvideReferrer() : null; if (referrer != null) { intent.putExtra(Intent.EXTRA_REFERRER, referrer); } if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); ActivityResult result = null; if (am.ignoreMatchingSpecificIntents()) { result = am.onStartActivity(intent); } if (result != null) { am.mHits++; return result; } else if (am.match(who, null, intent)) { am.mHits++; if (am.isBlocking()) { return requestCode >= 0 ? am.getResult() : null; } break; } } } } try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); int result = ActivityManager.getService() .startActivity(whoThread, who.getBasePackageName(), 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; }
到这里呢,AMS就知道要启动一个Activity了。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - startActivity()
public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId());
作者:Dufre
链接:https://www.jianshu.com/p/91ca5ac605be
共同学习,写下你的评论
评论加载中...
作者其他优质文章