Android系统服务的注册方式-1
一、概述
启动过程有采用过两种不同的方式来注册系统服务:
(1) ServiceManager 的 addService()
(2) SystemServiceManager 的 startService()
其核心都是向 ServiceManager 进程注册 binder 服务,但功能略有不同,下面从源码角度详加说明。
二、SM.addService 方式
这里以 InputManagerService 服务为例, 说明这类服务的启动方式:
inputManager = new InputManagerService(context, null); //先创建服务对象 ServiceManager.addService(Context.INPUT_SERVICE, inputManager); //[见小节2.1]
2.1 SM.addService
[-> ServiceManager.java]
public static void addService(String name, IBinder service) { try { //[见小节2.2 和 2.3] getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } }
2.2 SM.getIServiceManager
[-> ServiceManager.java]
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } //【见2.2.1】 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
采用了单例模式获取 ServiceManager getIServiceManager() 返回的是 ServiceManagerProxy(简称SMP)对象.
其中 BinderInternal.getContextObject(), 等价于 new BpBinder(0), handle=0 意味着指向的是远程进程 /system/bin/servicemanager中的 ServiceManager 服务.
2.2.1 asInterface
[-> ServiceManagerNative.java]
public abstract class ServiceManagerNative extends Binder implements IServiceManager { static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //创建ServiceManagerProxy对象[见小节2.2.2] return new ServiceManagerProxy(obj); } }
2.2.2 ServiceManagerProxy 创建
[-> ServiceManagerNative.java ::ServiceManagerProxy]
class ServiceManagerProxy implements IServiceManager { private IBinder mRemote; public ServiceManagerProxy(IBinder remote) { mRemote = remote; } ... }
可见, getIServiceManager() 过程是获取一个用于跟远程 ServiceManager 服务(这个用于管理所有binder服务的大管家)进行通信的binder代理端.
2.3 SMP.addService
[-> ServiceManagerNative.java ::ServiceManagerProxy]
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
通过 mRemote 向将 ADD_SERVICE_TRANSACTION 的事件发送给 ServiceManager. 接下来的内容见《Binder系列5—注册服务(addService)》.
三. SSM.startService 方式
通过这种方式启动的服务,有一个特点都必须是继承于 SystemService 对象, 这里以 PowerManagerService 为例来说明:
//[见小节3.1] mSystemServiceManager = new SystemServiceManager(mSystemContext); //[见小节3.2] mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
3.1 SSM初始化
[-> SystemServiceManager.java]
public class SystemServiceManager { private final Context mContext; //接收lifecycle事件的服务 private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); public SystemServiceManager(Context context) { mContext = context; } }
mSystemServiceManager 只会创建一次,后续其他服务通过该方式启动,直接调用其 startService() 方法即可。
3.2 SSM.startService
[-> SystemServiceManager.java]
public <T extends SystemService> T startService(Class<T> serviceClass) { final String name = serviceClass.getName(); //保证要启动的服务是继承于SystemService,否则抛出异常 if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException(...); } final T service; try { Constructor<T> constructor = serviceClass.getConstructor(Context.class); //通过反射创建目标服务类的对象 service = constructor.newInstance(mContext); } catch (Exception ex) { ... } //将该服务添加到mServices mServices.add(service); try { //执行服务的onStart过程 service.onStart(); } catch (RuntimeException ex) { ... } return service; }
mSystemServiceManager.startService(xxx.class) 功能主要:
(1) 创建xxx类的对象,执行该对象的构造函数;
(2) 将该对象添加到 mSystemServiceManager 的成员变量 mServices;
(3) 调用该对象的 onStart(); 只有通过SSM这种方式注册的才才会执行这个回调。
看到这并没有看到服务是如何注册到 ServiceManager, 这里继续以 PowerManagerService 为例,其实是在 onStart() 完成.
3.2.1 onStart
[-> PowerManagerService.java]
public void onStart() { //[见小节3.2.2] publishBinderService(Context.POWER_SERVICE, new BinderService()); publishLocalService(PowerManagerInternal.class, new LocalService()); Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); }
PowerManagerService 定义了一个内部类 BinderService, 继承于 IPowerManager.Stub 服务. 再调用 publishBinderService 来注册服务.
3.2.2 publishBinderService
[-> SystemService.java]
public abstract class SystemService { protected final void publishBinderService(String name, IBinder service) { publishBinderService(name, service, false); } protected final void publishBinderService(String name, IBinder service, boolean allowIsolated) { ServiceManager.addService(name, service, allowIsolated); } }
到此可见, 采用该方式真正注册服务的过程,同样也是采用 ServiceManager.addService 方式.
通过这种方式启动的服务, 都是继承于 SystemService 类, 那么这种方式启动的服务有什么特殊之处吗? 答应就是 startBootPhase 的过程:
3.3 SSM.startBootPhase
[–>SystemServiceManager.java]
public void startBootPhase(final int phase) { mCurrentPhase = phase; final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); try { service.onBootPhase(mCurrentPhase); } catch (Exception ex) { ... } }
所有通过该方式注册的继承于 SystemService 的服务,都会被添加到 mServices. 该方法会根据当前系统启动到不同的阶段, 则回调所有服务 onBootPhase() 方法
3.3.1 BootPhase
系统开机启动过程, 当执行到 system_server 进程时, 将启动过程划分了几个阶段, 定义在 SystemService.java 文件
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; public static final int PHASE_LOCK_SETTINGS_READY = 480; public static final int PHASE_SYSTEM_SERVICES_READY = 500; public static final int PHASE_ACTIVITY_MANAGER_READY = 550; public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; public static final int PHASE_BOOT_COMPLETED = 1000;
这些阶段跟系统服务大致的顺序图,如下:
PHASE_BOOT_COMPLETED=1000,该阶段是发生在 Boot完成 和 home应用启动完毕,对于系统服务更倾向于监听该阶段,而非监听广播 ACTION_BOOT_COMPLETED
四、总结
4.1 两种方式的区别
方式1. ServiceManager.addService():
功能:向 ServiceManager 注册该服务.
特点:服务往往直接或间接继承于 Binder 服务;
举例:input, window, package;
方式2. SystemServiceManager.startService:
功能:
(1) 创建服务对象;
(2) 执行该服务的 onStart() 方法;该方法会执行上面的 SM.addService();
(3) 根据启动到不同的阶段会回调 onBootPhase() 方法;
(4) 另外,还有多用户模式下用户状态的改变也会有回调方法;例如 onStartUser();
特点:服务自身或内部类继承于 SystemService;
举例:power, activity;
两种方式真正注册服务的过程都会调用到 ServiceManager.addService() 方法. 对于方式2多了一个服务对象创建以及 根据不同启动阶段采用不同的动作的过程。可以理解为方式2比方式1的功能更丰富。
参考:
Android系统服务的注册方式:http://gityuan.com/2016/10/01/system_service_common/
Binder系列4—获取ServiceManager: http://gityuan.com/2015/11/08/binder-get-sm/
Binder系列5—注册服务(addService):http://gityuan.com/2015/11/14/binder-add-service/#addservice
posted on 2023-08-15 13:54 Hello-World3 阅读(572) 评论(0) 编辑 收藏 举报