ActivityManagerService 与 APP 的进程间通信的一些梳理

由先前的文章:Android Launcher 启动 APP 流程的源码分析

可知,APP 向 ActivityManagerService(简称AMS)发起进程间通信,是通过IActivityManager接口。

代码:

// android/app/Instrumentation.java
int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);
// 追踪 ActivityManager.getService()
// android/app/ActivityManager.java
public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

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

从代码中看到,ActivityManager类的getService()函数内,通过ServiceManager类的getService()函数,得到代表AMS的IBinder接口,在通过Stub.asInterface的方式,转成IActivityManager的接口。然后就可以通过IActivityManager向AMS发起进程间通信。

那么,如果AMS想要向APP发起进程间通信,是通过什么接口呢?

答:IApplication接口,在APP被创建时,触发的函数:main->attach 将IApplication接口传过去的。

每个APP都有一个ActivityThread类, ActivityThread类的内部类ApplicationThread extends IApplicationThread.Stub。

ActivityManagerService 与 APP 的进程间通信的一些梳理_第1张图片

代码:

// android/app/ActivityThread.java

final ApplicationThread mAppThread = new ApplicationThread();

private void attach(boolean system) {
            ........
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
           .........
}


从代码中可见,通过IActivityManager接口,在调用的attachApplication函数中传递了IApplicationThread接口类型的mAppThread变量进去。


小结:

任何一个APP,向AMS发起进程间通信,都是通过IActivityManager接口来发起的,而获得IActivityManager接口的办法就是通过ServiceManager类的getService()函数,传递代表AMS的参数:Context.ACTIVITY_SERVICE("activity"),就可以拿到IActivityManager;同理,如果APP想跟WMS(WindowManagerService)发起进程间通信,也是通过ServiceManager类的getService()函数,传递代表WMS的参数:Context.WINDOW_SERVICE("window"),就可以拿到IWindowManager。

代码示例:

final IWindowManager wm = IWindowManager.Stub.asInterface(
                        ServiceManager.getService(Context.WINDOW_SERVICE));

如果是AMS,WMS向APP发起进程间通信,就需要这个APP的IApplication接口。

在AMS中,存在着一个记录正在运行的进程的数组变量:

/**
     * List of running applications, sorted by recent usage.
     * The first entry in the list is the least recently used.
     */
    final ArrayList mLruProcesses = new ArrayList();

一个APP在被创建后,出发的main函数->attach函数回向AMS发起进程间通信,并传递代表自身的IActivityManager接口,就是保存在AMS中的mLruProcesses变量中。


你可能感兴趣的:(ActivityManagerService 与 APP 的进程间通信的一些梳理)