Android SystemService 调用流程

最近在整理Usb 的默认MTP模式方案整理,涉及到app ->system server-> hal 流程,因为他们属于不同的进程,中间涉及到跨进程的调用,既然后面要写USB 流程,那么就用adb 的例子看看实际的调用流程.

app 如何调用System server 的服务?

直接看例子,两种方式

try{
           //方式一
            IBinder b = ServiceManager.getService(Context.ADB_SERVICE);
            IAdbManager service = IAdbManager.Stub.asInterface(b);

            Log.d("xss", "IBinder = "+service.toString());
            Log.d("xss", "IBinder = "+service.isAdbWifiQrSupported());
            Log.d("xss", "IBinder = "+service.getPairedDevices().toString());
            

            //方式二
            AdbManager adbManager =                          (AdbManager)getActivity().getSystemService(Context.ADB_SERVICE);
            Log.d("xss", "service = "+adbManager.toString());
            Log.d("xss", "service = "+adbManager.isAdbWifiQrSupported());
            //Log.d("xss", "IBinder = "+adbManager.getPairedDevices().toString());

        }catch(Exception e){
                Log.d("xss", "Exception = "+e.toString());
        }

方式一:

System app 可以调用,通过代理的方式调用,为什么普通app 不能这么调用呢?

        点进去看看就知道了,hide api ,所以普通的应用调用不了啦.

        /** @hide */

        public final class ServiceManager {

        }

方式二:

普通app 调用方式,写应用层面的比较常见这种方式,当然系统app也可以这么用.

两种方式有啥区别?

这个涉及到AIDL 的调用流程,因为涉及到两个进程(app ,system server),简单来说,方式二是暴露给app 进程的接口函数,最终调用的是方式一里面的函数,所以方式一的函数数量>=方式二的函数数量,明白?

画图解释下,我们先不管这个Service 哪来的,我们先对比下两种方式函数的差异.

 

可以看到 system server 通过方式一代理的方式直接调用 Service 中的函数,这些函数中有不想暴露给app 调用的,所有通过UsbManager 封装了一层,暴露上app,所以上面注释掉的方法,方式二调用不了,就是这个道理.

 //Log.d("xss", "IBinder = "+adbManager.getPairedDevices().toString());
 

Service 哪里来的?

 

这个获取的是服务对象,那这个服务是何时启动的呢?

UsbService

Lifecycle 可以理解为运行在系统进程的服务,启动的时候发布服务

**
 * UsbService manages all USB related state, including both host and device support.
 * Host related events and calls are delegated to UsbHostManager, and device related
 * support is delegated to UsbDeviceManager.
 */
public class UsbService extends IUsbManager.Stub {

    public static class Lifecycle extends SystemService {
        private UsbService mUsbService;
        //.......

        @Override
        public void onStart() {
            SystemServerInitThreadPool.submit(() -> {
                mUsbService = new UsbService(getContext());
                publishBinderService(Context.USB_SERVICE, mUsbService);
                mOnStartFinished.complete(null);
            }, "UsbService$Lifecycle#onStart");
        }

    }

    /**
     * Publish the service so it is accessible to other services and apps.
     *
     * @param name the name of the new service
     * @param service the service object
     */
    protected final void publishBinderService(@NonNull String name, @NonNull IBinder service) {
        publishBinderService(name, service, false);
    }

    /**
     * Get a binder service by its name.
     *
     * @hide
     */
    protected final IBinder getBinderService(String name) {
        return ServiceManager.getService(name);
    }

    /**
     * Publish the service so it is only accessible to the system process.
     *
     * @hide
     */
    protected final <T> void publishLocalService(Class<T> type, T service) {
        LocalServices.addService(type, service);
    }

    /**
     * Get a local service by interface.
     *
     * @hide
     */
    protected final <T> T getLocalService(Class<T> type) {
        return LocalServices.getService(type);
    }

    private SystemServiceManager getManager() {
        return LocalServices.getService(SystemServiceManager.class);
    }
}

打开SystemService 发现服务类型有两种:

BinderService  提供其他服务调用,和app (系统app ,三方app)

LocalService 仅仅是系统进程可以使用,即system server 内部调用.

如何添加自己的Service 给app 调用?

未完待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值