(转)ActivityManagerService启动过程(基于android 8.0)

it2022-05-05  90

转https://www.jianshu.com/p/8d4e17836322

下边这个图是7.0 的

 

AMS类的结构,copy自网络

 

1.看得出AMS 实现了看门狗(Watchdog.Monitor)以及电量监控(BatteryStatsImpl.BatteryCallback) 接口,并且继承了ActivityManagerNative 2.ActivityManagerNative实现了IActivityManager,使用Binder来跟应用程序进行通信,只不过这里AMN内部增加了一个代理类解藕,最终其他进程要跟AMS交互还是使用Binder机制。 这里很好玩的是8.0系统上ActivityManagerNative上已经被delete

/** * {@hide} * @deprecated will be removed soon. See individual methods for alternatives. */ @Deprecated public abstract class ActivityManagerNative

而且本身的AMS的继承类也相应的变化了:

public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

这里的它的区别是继承了IActivityManager.Stub 接口类,了解Bindler机制的人应该知道此处应该是一个IActivityManager.aidl生成的java类。只不过这里android可能删除了ActivityManagerNative这个类,并把一些Binder代码转化为了AIDL模版方式。 可以看下下边两个sdk中的代码: 8.0上: ActivityManagerNative.class中的代码:

/** * Retrieve the system's default/global activity manager. * * @deprecated use ActivityManager.getService instead. */ static public IActivityManager getDefault() { return ActivityManager.getService(); }

ActivityManager.class 中的代码:

public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };

7.0上: ActivityManagerNative.class中的代码:

/** *获得IActivityManager类 */ static public IActivityManager getDefault() { return gDefault.get(); } static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ActivityManagerProxy(obj);

ActivityManager.class 中的代码:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b);//注意这一行 if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };

可以看得出来,两个的写法不一样,本质上都是一样的,只不过这里android可能使用了统一的AIDL方式进行ipc,减少了代码的维护。所以我们在写ipc的时候还是使用aidl模版比较好,利于维护。

好了有点扯远了,回到正题上AMS的启动过程:

AMS的启动是在SystemServer(系统进程)中进行启动的,我们知道android所有的进程都是由zygote fork出来的,SystemServer也不例外。下边捋一下SystemServer的代码:

SystemServer

/** * The main entry point from zygote. */ //很清楚看到是由zygote进程fork来的 public static void main(String[] args) { new SystemServer().run(); }

run方法:

private void run() { .... (1) Looper.prepareMainLooper(); // Initialize native services. System.loadLibrary("android_servers"); .... (2) // Initialize the system context. createSystemContext(); (3) // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); .... (4) // Start services. try { traceBeginAndSlog("StartServices"); startBootstrapServices(); startCoreServices(); startOtherServices(); SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } .... // Loop forever. Looper.loop(); (5) throw new RuntimeException("Main thread loop unexpectedly exited"); } (1).Looper.prepareMainLooper();方法:

初始化MainLooper,这里可以看得出我们这个SystemServer本身可能就是一个应用进程。 这里稍微扩展一下Looper.prepareMainLooper()函数是创建了一个全局静态的sMainLooper,创建函数是:

private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }

1.这里我当时没想明白是怎么把ActivityThread跟Looper进行绑定的,毕竟ActivityThread是在Looper初始化之后new的,而Looper的new过程是伴随着绑定当前线程的。这里我们一定要注意: ActivityThread不是一个线程,尽管以此命名,我们new的ActivityThread只不过是一个普通类。同时行使主线程的能力罢了。 2.这里的Looper是使用sThreadLocal保证全局唯一的,ThreadLocal也是一个很有意思的类,它可以看作是一个Map的工具类,使用统一的工具类管理各个分散在不同Thread中的ThreadLocalMap,以ThreadLocal为key,管理各个thread中map值,当然这里必须使用弱引用防止内存问题。这种统一管理方式很值得学习。

(2)createSystemContext方法:

1.得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程; 2.得到了一个Context对象,对于SystemServer而言,它包含的Application运行环境与framework-res.apk有关。

private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); } public static ActivityThread systemMain() { // The system process on low-memory devices do not get to use hardware // accelerated drawing, since this can add too much overhead to the // process. if (!ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true); return thread; } (3)创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。(5)throw new RuntimeException("Main thread loop unexpectedly exited");

这里一种防止Looper quit的一种方式

(4) 启动各种service,这里startBootstrapServices ()方法是初始化AMS的,只需要看此方法即可 private void startBootstrapServices() { .... Installer installer = mSystemServiceManager.startService(Installer.class); .... // Activity manager runs the show. //真正启动AMS的地方 mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); .... // Set up the Application instance for the system process and get started. //注册一些系统服务 //将framework-res.apk的信息加入到SystemServer对应的LoadedApk中, //同时构建SystemServer进程对应的ProcessRecord, 以将SystemServer进程纳入到AMS的管理中。 mActivityManagerService.setSystemProcess(); .... }

可以看出AMS是使用SystemServiceManager(SSM)启动的,SSM启动的service必须继承自final Class<SystemService> serviceClass;,但是这里因为AMS并不是,所以使用了ActivityManagerService.Lifecycle.class类。

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(); } public ActivityManagerService getService() { return mService; } }

很简单这只不过是AMS 的代理类,也是为了解藕,这种启动Service的处理方式蛮特别的。可以学习下SystemServiceManager的源码,这里不做深入。

这里Lifecycle.class中有两步操作 ,

mService = new ActivityManagerService(context); // Note: This method is invoked on the main thread but may need to attach various // handlers to other threads. So take care to be explicit about the looper. public ActivityManagerService(Context systemContext) { ... mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); mAppErrors = new AppErrors(mUiContext, this); ... Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); }

可以看得出来AMS的构造方法中都是一些初始化操作,以及增加了看门狗

mService.start(); private void start() { //完成统计前的复位工作 removeAllProcessGroups(); //开始监控进程的CPU使用情况 mProcessCpuThread.start(); //注册服务 mBatteryStatsService.publish(mContext); 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"); } }

主要处理了: 1、启动CPU监控线程。该线程将会开始统计不同进程使用CPU的情况。 2、发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的继承ActivityManagerInternal的服务。

看上边的startBootstrapServices方法中mActivityManagerService.setSystemProcess()方法

public void setSystemProcess() { try { ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo", new MemBinder(this)); ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); ServiceManager.addService("dbinfo", new DbBinder(this)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(this)); } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); 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 e) { throw new RuntimeException( "Unable to find android system package", e); } }

此方法中主要处理了 1、注册一些服务; 2、获取package名为“android”的应用的ApplicationInfo; 3、调用ActivityThread的installSystemApplicationInfo; 4、AMS进程管理相关的操作。

这里注意installSystemApplicationInfo ()方法:它主要处理了将package名为“android”的应用的ApplicationInfo;(即framework-res.apk,资源apk)赋值给LoadedApk,这里不详细拆分 在SystemServer.run()下startOtherServices();方法中有一类似的代码mActivityManagerService.installSystemProviders();此方法是加载运行在SystemServer进程中的ContentProvider,即SettingsProvider.apk (定义于frameworks/base/packages/SettingsProvider)。最终ContentProvider信息都将注册到AMS中的mProviderMap集合中。

最后一步SystemSever#startOtherServices中调用ActivityManagerService#systemReady方法

public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) { ... //通知一些服务可以进行systemReady相关的工作,并进行启动服务或应用进程的工作 ... //开启HomeActivity startHomeActivityLocked(currentUserId, "systemReady"); ... }

到此我们的AMS已经启动完全,后续是Activity的启动流程,这里不做讲解。

鉴于时间限制,我就盗用下边的流程图作为总结吧。。。。

 

AMS的启动流程图

其他:

AMS的通信机制:(使用AIDL)

APP向AMS发起进程间通信:(IActivityManager.aidl) ActivityManger.getService() 获得AMS的Binder接口,在通过Stub.asInterface的方式,转成IActivityManager的接口。然后就可以通过IActivityManager向AMS发起进程间通信。

// android/app/Instrumentation.java int result = ActivityManager.getService() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, requestCode, 0, null, options); // android/app/ActivityManager.java public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };

AMS向APP发起进程间通信:(IApplication.aidl) 在AMS内部持有每个ActivityThread的IApplication接口实例,用时可以直接调用。当然这里也是Binder通信。 其实在ActivityThread.main()时会调用attach(bool)方法

private void attach(boolean system) { ... if (!system) { ... final IActivityManager mgr = ActivityManager.getService(); try { //将IApplication注册给AMS mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ... } @Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { ... attachApplicationLocked(thread, callingPid); ... } } private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ... updateLruProcessLocked(app, false, null); ... final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client) { ... //AMS中 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); mLruProcesses.add(app); ...

反正一系列的方法最后将IApplication传递到了AMS中,等到AMS调用APP时使用。看下图:

 

AMS跟应用进程通信

AMS本身运行在SystemServer 中,但同时也管理SystemServer(可以看作一个特殊APP)

SettingProvider.apk

SettingProvider.apk 给Settings应用提供设置默认值、设置存储和设置修改服务。其源码在frameworks/base/packages目录下。其apk在设备上的位置:/system/priv-app/SettingsProvider。本次对SettingProvider的修改主要针对一些设置默认值

Framework-res.apk

系统默认的一些资源信息

tag:AMS启动流程,通信机制

 


最新回复(0)