android6.0源码分析之AMS服务源码分析
2016-06-17 15:18
731 查看
activitymanagerservice服务源码分析
1、ActivityManagerService概述
ActivityManagerService(以下简称AMS)作为android中最核心的服务,主要负责系统的四大组件的启动、切换、调度以及应用进程的管理和调度等工作。它类似于操作系统中的进程管理和调度模块类似,所以要想掌握android,AMS至关重要。AMS属于service的一种,所以它也是由system_server进行启动以及管理。本文将以两条不同的主线来分析AMS:第一条与其他服务一样,分析system_server中AMS的调用轨迹;第二条将分析一个Activity的启动过程,而Activity的启动过程将在下一篇中进行分析。先来看AMS的家族图谱:
图中有一个ActivityManager类,由于ActivityManagerService是系统的核心服务,很多API不能开放给客户端使用,所以在家族图谱中增加了ActivityManager类,ActivityManager类通过调用ActivityManagerNative的getDefault函数来得到一个ActivityManagerProxy对象,通过它就可以实现ActivityManager与AMS的交互。
2、AMS的调用流程分析
AMS作为系统的核心服务,由system_server创建,system_server由Zygote进程的startsystemserver触发,此处以android6.0源码为基础,分析其run函数:private void run(){ ... //初始化native servers System.loadLibrary("android_servers"); ... //初始化system context createSystemContext(); //创建System service manager mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class,mSystemServiceManager); //start services try{ startBootstrapservices(); startCoreServices(); startOtherServices(); }catch(Throwable ex){ throw ex; } ... Looper.loop(); ... }
2.1 createSystemContext()方法分析
private void createSystemContext(){ //创建一个ActivityThread对象,它代表应用进程的主线程 ActivityThread activityThread = ActivityThread.systemMain(); //获取一个和应用进程一样的android运行上下文环境 mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); }
首先分析ActivityThread的systemMain()方法,其代码如下:
public static ActivityThread systemMain(){ ... ActivityThread thread = new ActivityThread(); thread.attach(true); return thread; }
由代码可知,其确实创建了一个ActivityThread对象,并调用其attach函数,记住,此处attach函数传入的参数为true,而在分析Activity启动的时候,它会为false,到时再对比分析。此处继续分析attach函数:
private void attach(boolean system) { ... if (!system) {//此处为true,所以不会执行此处代码 ... android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } ... } else {//执行此分支 android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { mInstrumentation = new Instrumentation(); //由ContextImol创建Context对象 ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } catch (Exception e) { } } //添加Dropbox logging 到libcore DropBox.setReporter(new DropBoxReporter()); ViewRootImpl.addConfigCallback(new ComponentCallbacks2(){ ... }); ... }
由于此处为系统服务,所以会执行else分支的代码,创建一个context对象,并且会根据Package信息来初始化一个Application对象。接着分析ActivityThread的getSystemContext()方法:
public ContextImpl getSystemContext(){ Synchronized(this){ if(mSystemContext == null){ mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; } }
显然,如果systemMain方法中创建Context成功,则返回,否则新建Context对象,综上,createSystemContext()方法主要功能就是,创建一个ActivityThread对象和一个ContextImpl对象,而这两个对象即组成了android运行环境。
时序图如下:
2.2 startBootstrapServices()方法分析
先看核心代码:private void startBootStrapServices(){ //启动Installer服务 Installer installer = mSystemServiceManager.startService(Installer.class); //启动ActivityManagerService服务 mActivityManagerService = mSystemServiceManager. startService(ActivityManagerService.Lifecycle.class).getService(); //启动PowerManagerService服务 mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); ... //初始化属性缓存 AttributeCache.init(mSystemContext); mActivityManagerService.setSystemProcess(); startSensorService(); }
代码中,会将一系列的服务添加到servicemanager管理,主要包括Installer,AMS,PMS等系统服务,并初始化属性缓存,最后会调用AMS的setSystemProcess()方法将sytem_server进程并入AMS的管理范围,继续分析setSystemProcess()方法:
public void setSystemProcess(){ try{ //添加ActvityManagerService等服务到ServiceManager ServiceManager.addService(Context.ACTIVITY_SERVICE,this,true); ... ServiceManager.addService("meminfo",new MemBinder(this)); ServiceManager.addService("gfxinfo",new GraohicsBinder(this)); ServiceManager.addService("dbinfo"new DbBinder(this)); ... //从packagemanagerservice中获取ApplicationInfo信息 ApplicationInfo info = mContext.getPackageManager() .getApplicationInfo("android",STOCK_PM_FLAGS); //根据info初始化android运行环境,即ActivityThread以及ContextImpl对象 mSystemThread.installSystemApplicationInfo(info,getClass().getClassLoader()); synchronized(this){ //创建新的进程 ProcessRecord app = newProcessRecordLocked(info,info.processName,false,0); app.persistent = true; app.pid = MY_PID; app.maxAdj = ProcessList.SYSTEM_ADJ; //绑定主线程 app.makeActive(mSystemThread.getApplicationThread(),mProcessStats); synchronized(mPidsSelfLocked){ mPidsSelfLocked.put(app.pid,app); } //更新进程管理 updateLruProcessLocked(app,false,null); updateOomAdjLocked(); }catch(PackageManager.NameNotFoundException ex){ throw new RuntimeException("unable to find android system package",ex); } } }
首先分析installSystemApplicationInfo方法,它依次调用ActivityThread->ContextImpl->LoadedApk等的installSystemApplicationInfo方法,LoadedApk中的代码如下:
void installSystemApplicationInfo(ApplicationInfo info,ClassLoader classLoader){ assert info.packageName.equals("android"); mApplicationInfo = info; mClassLoader = classLoader; }
显然,是根据先前从Package里面获取的ApplicationInfo对系统的应用信息进行初始化,主要包括ApplicationInfo以及ClassLoader对象。
接着,分析创建新进程的方法newProcessRecordLocked():
final ProcessRecord newProcessRecordLocked(ApplicationInfo info,String customProcess, boolean isolated,int isolatedUid){ ... final ProcessRecord r = new ProcessRecord(stats,info,proc,uid); ... addProcessNameLocked(r); return r; }
它首先创建一个进程对象ProcessRecord,并将其加入到自定义的ProcessMap类型的容器里,最后返回。
最后,分析更新进程管理updateLruProcessLocked()方法:
final updateLruProcessLocked(ProcessRecord app,boolean activityChange,ProcessRecord client){ final boolean hasActivity = app.activities.size()>0||app.hasClientActivities ||app.treatLikeActivity; final boolean hasService = false;//android 6.0没实现 //如果没有Activity切换,切当前进程有Activity存在,则进程调度直接返回 if(!activityChange&&hasActivity){ return; } ... //记录下一个进程的索引 int nextIndex; if(hasActivity){ //获取Lru进程表中进程的数量 final int N = mLruProcesses.size(); //该进程没有activity,而进程表中其他进程有activity if(app.activities.size() == 0&&mLruProcessActivityStart<(N-1)){ //将进程加入进程表 mLruProcesses.add(N-1,app); ...//将其调整到第二个进程位置 }else{//如果该进程有activity //直接将其加入到Lru进程表顶端 mLruProcesses.add(app); } nextIndex = mLruProcessesServiceStart; }else if(hasService){ //如果有service存在,将它加入到service链表的顶端 mLruProcesses.add(mLruProcessActivityStart,app); nextIndex = mLruProcessServiceStart; mLruProcessServiceStart++; }else{ //如果是新建进程 int index = mLruProcessServiceStart; if(client!=null){ int clientIndex = mLruProcesses.lastIndexOf(client); if(clientIndex <= lrui){ clientIndex = lrui; } if(clientIndex >= 0&&index > clientIndex){ index = clientIndex; } } mLruProcesses.add(index,app); ... } ... }
此段代码就是进程LRU进程调度,具体参考注释。
小结:startBootStrapServices()主要是进行一系列的服务的注册,并且初始化进程信息,并将其加入到Lru进程表进行调度,同时也将System_server进程纳入AMS的管理。
2.3 startOtherServices()方法分析
与ActivityManagerService有关的核心代码如下:private void startOtherServices(){ final Context context = mSystemContext; //启动一系列的服务,CameraService,Account Manager,Telephony registry等 ... //启动settingProvider,它提供配置信息 mActivityManagerService.installSystemProviders(); ... //初始化窗口管理服务 wm = WindowManagerService.main(content,inputManager,mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,!mFirstBoot,mOnlyCore); ServiceManager.addService(Context.WINDOW_SERVICE,wm); ServiceManager.addService(Context.INPUT_SERVICE,inputManager); //在内部保存窗口管理服务WMS mActivityManagerService.setWindowManager(wm); ... //和WMS交互,弹出“启动进度”对话框 mActivityManagerNative.getDefault().showBootMessage(context.getResources().getText( com.android.internal.R.String.android_upgrading_starting_apps)); ... mActivityManagerService.systemReady(new Runnable(){ @Override public void run(){ ... //标记服务(services)准备完毕 mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY); ... try{ //启动桌面 startSystemUi(context); } ... } }); }
首先,分析installSystemProviders()方法:
public final void installSystemProviders(){ List<ProviderInfo> providers; synchronized(this){ ProcessRecord app = mProcessNames.get("system",Process.SYSTEM_UID); //根据进程名以及进程uid向PKMS查询满足要求的ProviderInfo providers = generateApplicationProvidersLocked(app); ... } if(providers != null){ mSystemThread.installSystemProviders(providers); } ... }
从进程Map表里,根据进程名字system来获取进程,并根据进程app来获取其应用信息中的providers,接着调用ActivityThread的installSystemProviders()方法来进行配置信息解析。
//ActivityThread.java public final void installSystemProviders(List<ProviderInfo> providers){ if(providers != null){ installContentProviders(mInitialApplication,providers); } }
跟踪installContentProviders()方法:
private void installContentProviders(Context context,List<ProviderInfo> providers){ final ArrayList<IActivityManager.ContentProviderHolder> results = new ArrayList<IActivityManager.ContentProviderHolder>(); for(ProviderInfo cpi:providers){ //通过调用istallProvider函数获得一个ContentProviderHolder对象 IActivityManager.ContentProviderHolder cph = installProvider(context,null,cpi,false ,true,true); if(cph != null){ cph.noReleaseNeeded = true; //保存获得的cph对象 results.add(cph); } } try{ //调用AMS的publishContentProvider注册此前的results里的cph。 ActivityManagerNative.getDefault().publishContentProviders(getApplicationThread(), results); }catch(RemoteException ex){ } }
从代码可以看出,首先调用installProvider函数获得一个ContentProviderHolder对象,并将其保存在容器中,最后在调用AMS的publishContentProvider来注册容器中的所有ContentProviderHolder对象。至此,一个SettingProvider对象就正式的注册到了AMS.
继续分析startOtherServices()方法中mActivityManagerService.systemReady(final Runnable goingcallback)方法:
public void systemReady(final Runnable goingCallback){ synchronized(this){ if(mSystemReady){//系统已经准备好,直接调用goingCallback的run方法,而我们此处为false if(goingCallbak != null){ goingCallback.run(); } return; } ... if(!mDidUpdate){//检查是否有升级更新 if(mWaitingUpdate){ return; } final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); //发送PRE_BOOT_COMPLETE广播 mWaitingUpdate = deliverPreootCompleted(new Runnable(){ public void run(){ synchronized(ActivityManagerService.this){ mDidUpdate = true; } showBootMessage(mContext.getText(R.string.android_upgrading_complete),false); writeLastDonePreBootReceivers(doneReceivers); //此处调用函数本身,再次执行 systemReady(goingCallback); } },doneReceivers,UserHandle.USER_OWNER); if(mWaitingUpdate){ return; } mDidUpdate = true; } mAppOpsService.systemReady(); //将mSystemReady标记为true,即表示系统准备好 mSystemReady = true; } ... retrieveSettings(); loadResourcesOnSystemReady(); synchronized(this){ readGrantedUriPermissionsLocked(); } //此处执行函数传入的回调的run方法,主要是启动SystemUIService if(goingCallback != null){ goingCallback.run(); } ... synchronized(this){ if(mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL){ try{ //从PKMS中找出所有persistent属性为1的ApplicationInfo List apps = AppGlobals.getPackageManager().getPersistentApplications( STOCK_PM_FLAGS); if(apps != null){ int N = apps.size(); int i; for(i=0;i<N;i++){ ApplicationInfo info = (ApplicationInfo)apps.get(i); if(info != null&&!info.packageName.equals("android")){ //逐个启动该Application所在的进程 addAppLocked(info,false,null); } } } } } } ... //启动初始化Activity mBooting = true; startHomeActivityLocked(mCurrentUserId,"systemReady"); ... mStackSupervisor.resumeTopActivitiesLocked(); sendUserSwitchBroadcastsLocked(-1,mCurrentUserId); } }
首先,检查系统是否是更新,并发送PRE_BOOT_COMPLETE广播,并将mSystemReady置为true。接着调用函数传入的回调goingCallback的run方法,在run方法中主要功能是启动SystemUIService服务,其代码如下:
static final void startSystemUi(Context context){ Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); context.startServiceAsUser(intent,UserHandle.OWNER); }
它主要是启动了一个SystemUIService服务,此服务由SystemUi.apk提供,实现了状态栏。执行了回调之后,systemReady方法接着,从PKMS中找出所有persistent属性为1的ApplicationInfo,并将其所在的进程逐个启动,最后再调用startHomeActivityLocked来启动Home界面,
总结:到此时,从system_server进程开始,着重分析了ActivityManagerService服务的启动过程,至此,整个系统准备完毕,此处不详细分析Home的启动过程,它的启动将会在Activity的启动过程中进行详细的分析,而Home启动成功后,AMS会发送ACTION_BOOT_COMPLETED广播。AMS的启动流程很复杂,下面给出整体的时序图:
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories