如何使用AMS
这篇文章主要讲解了“如何使用AMS”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用AMS”吧!
站在用户的角度思考问题,与客户深入沟通,找到石柱土家族网站设计与石柱土家族网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站制作、成都做网站、企业官网、英文网站、手机端网站、网站推广、域名注册、网站空间、企业邮箱。业务覆盖石柱土家族地区。
服务的启动
之前在SystemServer章节说过,系统的服务一般都是通过SystemServer进程启动的,AMS也不例外。
//SystemServer.java private void startBootstrapServices() { //... // Activity manager runs the show. traceBeginAndSlog("StartActivityManager"); mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); traceEnd(); } //中间用到了反射,之前说过。 public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = SystemClock.elapsedRealtime(); try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } } //ActivityManagerService.java public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; public Lifecycle(Context context) { super(context); mService = new ActivityManagerService(context); } @Override public void onStart() { mService.start(); } @Override public void onBootPhase(int phase) { mService.mBootPhase = phase; if (phase == PHASE_SYSTEM_SERVICES_READY) { mService.mBatteryStatsService.systemServicesReady(); mService.mServices.systemServicesReady(); } } @Override public void onCleanupUser(int userId) { mService.mBatteryStatsService.onCleanupUser(userId); } public ActivityManagerService getService() { return mService; } }
可以看到,通过调用了ActivityManagerService.Lifecycle这个内部类中的onStart方法,启动了AMS,并调用了AMS的start方法。
再简单看看AMS的实例化方法和start方法:
public ActivityManagerService(Context systemContext) { mContext = systemContext; mFactoryTest = FactoryTest.getMode(); mSystemThread = ActivityThread.currentActivityThread(); mUiContext = mSystemThread.getSystemUiContext(); mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); mHandlerThread.start(); mHandler = new MainHandler(mHandlerThread.getLooper()); mUiHandler = mInjector.getUiHandler(this); //... mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); mAppErrors = new AppErrors(mUiContext, this); // TODO: Move creation of battery stats service outside of activity manager service. mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.scheduleWriteToDisk(); mOnBattery = DEBUG_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); mStackSupervisor = createStackSupervisor(); mStackSupervisor.onConfigurationChanged(mTempConfig); mActivityStartController = new ActivityStartController(this); mRecentTasks = createRecentTasks(); mStackSupervisor.setRecentTasks(mRecentTasks); mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler); mLifecycleManager = new ClientLifecycleManager(); mProcessCpuThread = new Thread("CpuTracker") //... } private void start() { removeAllProcessGroups(); mProcessCpuThread.start(); mBatteryStatsService.publish(); mAppOpsService.publish(mContext); Slog.d("AppOps", "AppOpsService published"); LocalServices.addService(ActivityManagerInternal.class, new LocalService()); // Wait for the synchronized block started in mProcessCpuThread, // so that any other acccess to mProcessCpuTracker from main thread // will be blocked during mProcessCpuTracker initialization. try { mProcessCpuInitLatch.await(); } catch (InterruptedException e) { Slog.wtf(TAG, "Interrupted wait during start", e); Thread.currentThread().interrupt(); throw new IllegalStateException("Interrupted wait during start"); } }
代码很长,我只截取了一部分。
在构造函数中,主要初始化了一些对象,比如Context、ActivityThrad、Handler、CPU监控线程,还有一些后文要用到的ActivityStackSupervisor、ActivityStarter等对象,
在start方法中,主要就是启动了CPU监控线程,然后注册了电池状态服务和权限管理服务。
初始工作
AMS被启动之后,还会在SystemServer启动三大服务的时候偷偷干一些工作,我们搜索下mActivityManagerService变量就可以看到:
private void startBootstrapServices() { //1、初始化电源管理器 mActivityManagerService.initPowerManagement(); //2、为系统进程设置应用程序实例并启动。 mActivityManagerService.setSystemProcess(); } private void startCoreServices() { // 启动UsageStatsManager,用于查询应用的使用情况 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); traceEnd(); } private void startOtherServices() { //安装系统的Providers mActivityManagerService.installSystemProviders(); //启动WMS,并为AMS设置WMS关系 wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore, new PhoneWindowManager()); mActivityManagerService.setWindowManager(wm); //... } public void setSystemProcess() { try { ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); } }
其中第二步setSystemProcess方法中,会注册AMS到ServiceManager中,这样后续如果需要用到AMS的时候就可以通过ServiceManager进行获取,下面马上就要讲到。
启动就说这么多,都是比较枯燥的内容,所以也没有深入下去,有个印象就行,以后如果需要用到相关知识就知道去哪里找了。
从启动流程看AMS工作内容
为了了解AMS的具体工作,我们就从Activity的启动过程看起。
上文app启动流程中说过,startActivityForResult方法会转到mInstrumentation.execStartActivity方法:
//mInstrumentation.execStartActivity 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); public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final SingletonIActivityManagerSingleton = new Singleton () { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
可以看到,最终要拿到AMS的IBinder类型引用,这里的ServiceManager.getService(Context.ACTIVITY_SERVICE)是不是有点熟悉,没错,就是刚才专门调用了setSystemProcess方法对AMS进行了注册在ServiceManager中。然后我们要使用相关服务的方法的时候,就通过Servermanager拿到对应服务的引用。
这里也就是拿到了IActivityManager对象,IActivityManager其实就是AMS在当前进程的代理,这里的逻辑就是通过AIDL做了一个进程间的通信。因为这些服务,包括我们今天说的AMS都是在SystemServer进程中的,而我们实际用到的时候是在我们自己的应用进程中,所以就涉及到进程间通信了,这里是用的Binder机制进行通信。
Binder,ServiceManager,这是Binder通信一整套流程,不光是AMS,包括其他的WMS等服务基本上都是通过Binder机制进行进程间通信的,具体内容可以期待下后面说到的Binder章节。
接着看启动流程,通过Binder调用到了AMS的startActivity方法,然后会调用到ActivityStarter的startActivity方法,在这个方法中,我们发现一个新的类:
//ActivityStarter.java private int startActivity(...){ ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, checkedOptions, sourceRecord); if (outActivity != null) { outActivity[0] = r; } //... return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); }
ActivityRecord
这个类翻译过来是Activity的记录,所以猜测是和Activity有关,我们点进去看看它里面包含了什么:
final ActivityManagerService service; // owner final IApplicationToken.Stub appToken; // window manager token final ActivityInfo info; // all about me ApplicationInfo appInfo; // information about activity's app final int userId; // Which user is this running for? final String packageName; // the package implementing intent's component final String processName; // process where this component wants to run final String taskAffinity; // as per ActivityInfo.taskAffinity private int icon; // resource identifier of activity's icon. private int logo; // resource identifier of activity's logo. private int theme; // resource identifier of activity's theme. int launchMode; // the launch mode activity attribute.
我保留了一些比较常用的属性,大家应该都看得出来是什么了吧,比如当前Activity的主题——theme,当前Activity的token——apptoken,当前Activity的包名——packageName。
所以这个ActivityRecord其实就是保存记录了Activity的所有信息。
接着看流程,后续会执行到startActivityUnchecked方法,这个方法中,我们又可以看到一个新的类——TaskRecord.
TaskRecord
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { newTask = true; result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack); } else if (mSourceRecord != null) { result = setTaskFromSourceRecord(); } else if (mInTask != null) { result = setTaskFromInTask(); } else { // This not being started from an existing activity, and not part of a new task... // just put it in the top task, though these days this case should never happen. setTaskToCurrentTopOrCreateNewTask(); } } // 新建一个任务栈 private void setTaskToCurrentTopOrCreateNewTask() { //... final ActivityRecord prev = mTargetStack.getTopActivity(); final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord( mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info, mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions); addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask"); mTargetStack.positionChildWindowContainerAtTop(task); } //添加Ac到栈顶 private void addOrReparentStartingActivity(TaskRecord parent, String reason) { if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) { parent.addActivityToTop(mStartActivity); } else { mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason); } }
从代码中可知,当我们启动的Activity需要一个新的任务栈的时候(比如启动模式为FLAG_ACTIVITY_NEW_TASK),我们会走到setTaskToCurrentTopOrCreateNewTask方法中,新建一个TaskRecord类,并且把当前的Activity通过addActivityToTop方法添加到栈顶。
所以这个TaskRecord类就是一个任务栈类了,它的作用就是维护栈内的所有Activity,进去看看这个类有哪些变量:
final int taskId; // Unique identifier for this task. /** List of all activities in the task arranged in history order */ final ArrayListmActivities; /** Current stack. Setter must always be used to update the value. */ private ActivityStack mStack;
这里截取了一些,可以发现有任务id——taskId,任务栈的所有ActivityRecord——mActivities,以及这个还不知道是什么的但是我知道是用来管理所有Activity和任务栈的大管家——ActivityStack。
ActivityStack
启动流程再往后面走,就会走到的ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法:
//ActivityStackSupervisor.java /** The stack containing the launcher app. Assumed to always be attached to * Display.DEFAULT_DISPLAY. */ ActivityStack mHomeStack; /** The stack currently receiving input or launching the next activity. */ ActivityStack mFocusedStack; /** If this is the same as mFocusedStack then the activity on the top of the focused stack has * been resumed. If stacks are changing position this will hold the old stack until the new * stack becomes resumed after which it will be set to mFocusedStack. */ private ActivityStack mLastFocusedStack; public ActivityStackSupervisor(ActivityManagerService service, Looper looper) { mService = service; mLooper = looper; mHandler = new ActivityStackSupervisorHandler(looper); } boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || !r.isState(RESUMED)) { mFocusedStack.resumeTopActivityUncheckedLocked(null, null); } else if (r.isState(RESUMED)) { // Kick off any lingering app transitions form the MoveTaskToFront operation. mFocusedStack.executeAppTransition(targetOptions); } return false; }
ActivityStackSupervisor是一个管理ActivityStack的类,在AMS的构造方法中被创建,这个类中可以看到有一些任务栈,比如mHomeStack——包含了Launcher APP的Activity。
然后再看看ActivityStack这个大管家家里存储了什么好东西:
enum ActivityState { INITIALIZING, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED, FINISHING, DESTROYING, DESTROYED } private final ArrayListmTaskHistory = new ArrayList<>(); final ArrayList mLRUActivities = new ArrayList<>(); ActivityRecord mPausingActivity = null; ActivityRecord mLastPausedActivity = null;
可以看到,在ActivityStack中:
有一个枚举ActivityState,存储了Activity的所有状态。
有一些TaskRecord和ActivityRecord的列表,比如mTaskHistory——没有被销毁的任务栈列表,mLRUActivities——通过LRU计算的列表头目是最近最少使用的Activity的ActivityRecord列表。
还有一些特殊状态的Activity对应的ActivityRecord,比如正在暂停的Activity,上一个暂停过的Activity。
最后,启动流程会走到AMS的startProcessLocked方法,然后跟Zygote进程通信,fork进程。后续就不说了。
感谢各位的阅读,以上就是“如何使用AMS”的内容了,经过本文的学习后,相信大家对如何使用AMS这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!
新闻标题:如何使用AMS
标题路径:http://myzitong.com/article/gdhdho.html