SystemServiceRegistry中FingerprintManager注册和服务获取以及泛型的使用

本文以FingerprintManager为例,介绍如何实现应用通过context.getSystemService()获取一个FingerprintManager远程服务对象.
以及FingerprintManger和FingerprintService的注册过程

一.注册SystemService
SystemServiceRegistry.java
1.两个hashmap

1.1 hashmap SYSTEM_SERVICE_NAMES
hashmap的类型为 HashMap<Class<?>, String>,用以建立类名和类对象之间的索引关系.
一个输入参数为Class<?>,这里的<?>使用了通配符?,表示泛化的Class对象的引用,效果上和直接使用Class是相同的.表示的都是非具体的类应用. 使用Class<?>而不使用Class的好处是表示并非是由于疏忽使用了一个非具体的类引用,而是就是选择了非具体的版本
另一个参数很明确了,就是String对象的引用
该HashMap容器表示可以持有任意类对象的引用,并且与一组String对象(类的名字)关联起来
应用可以通过类对象查询到对应的类名
1.2 hashmap SYSTEM_SERVICE_FETCHERS
其中ServiceFetcher<?>为实现了ServiceFetcher<?>接口的对象的引用,该hashmap用来就建立类名和对应的ServiceFetcher<?>对象的索引关系
应用可以通过类名获取到对应的远程服务对象
2.system service注册
接下里有一组静态函数用来进行system service注册.如下:
2.1.registerService函数
该方法为一个泛型方法:
泛型的声明,必须在方法的修饰符(public,static,final,abstract等)之后,返回值声明之前。
public static <T> T request2Bean(HttpServletRequest request,Class<T> clazz){}
其中第一个<T>是与传入的参数Class<T>相对应的,相当于返回值的一个泛型,后面的T是返回值类型,代表方法必须返回T类型的(由传入的Class<T>决定)
例如
是否拥有泛型方法,与其所在类或者接口是否是泛型没有关系
2.2.CachedServiceFetcher<FingerprintManager>对象
创建一个CachedServiceFetcher<FingerprintManager>对象用以加入到hashmap SYSTEM_SERVICE_FETCHERS中.
首先要明确,CachedServiceFetcher是一个 泛型类,由于CachedServiceFetcher<T>是一个使用了泛型类,因此在创建对象时,需要确定T为FingerprintManager
泛型类的说明:
2.2.1.
该泛型类实现了泛型接口
泛型接口:
这属于泛型接口
而接口中的
则属于泛型方法,在这个方法之前并没有进行泛型的声明,应该是在接口中已经进行了泛型声明的缘故
2.2.2
从接口中的getService()方法 (实际上这就是context.getSystemService的实现)的实现可以看到,如果服务从未被创建过,则调用createService的实现创建service
2.2.3.
mCacheIndex为累加index
2.3同时,CachedServiceFetcher<T>是一个抽象类,因此对象需要实现其抽象方法createService
2.4其实现为通过ServiceManager.getService()获得一个fingerprintService远程对象.并且将这个对象作为参数传入FingerprintManager的构造函数,创建一个FingerprintManager对象并返回.
2.5字符串的定义位于Context.java


以上注册工作全部完成.实际上就是在hashmap中建立一个Context.FINGERPRINT_SERVICE字符串与CachedServiceFetcher<FingerprintManager>对象的索引.

获取Context.FINGERPRINT_SERVICE服务,也就是应用调用的 context.getSyetemService()的实现:
1.去hashmap中查找类名称对应的实现了ServiceFetcher接口的对象.注意这里返回的是ServiceFetcher<?>对象,而不是CachedServiceFetcher<T>对象.在注册时,put到SYSTEM_SERVICE_NAMES hashmap中的,除了CachedServiceFetcher<T>对象,还有StaticServiceFetcher<T>对象.他们都实现了ServiceFetcher<?>接口.在这里做了 向上转型.
2.如果查找到fetcher对象,则调用对象的getService方法创建

二.将FingerprintService注册成为系统服务
以上分析了FingerprintManager服务的注册(实际上它是FIngerprintService的包裹层),接下来还需要分析FingerprintService是如何注册到serviceManager的,即:
FingerprintService是怎样成为系统服务的?
1.FingerprintService.aidl文件
通过ServiceManager获得的IFingerprintService对象是由AIDL文件定义的
位于frameworks\base\core\java\android\hardware\fingerprint\FingerprintService.aidl
其实现位于 FingerprintService.java
Stub类系由aidl文件自动生成

2.首先我们需要启动FingerprintService
SystemServer,java
源自zygote....android启动后的第一个进程
>>
>>
在比较靠后的位置,找到了启动FingerprintService部分
>>
2.1先将FingerprintService class对象加入到ServiceManager自己维护的一个ArrayList mServices中
2.2调用FingerprintService的onStart方法

注:这里的启动服务使用的是startService方法.而类似震动服务的启动方式则为
先创建实例.再使用addService方法.
这两种方式有何区别?

3.接下来进入FingerprintService
FingerprintService.java
>>
在其onStart方法中
3.1 将FingerprintServiceWrapper对象分注册到ServiceManager,并且与Context.FINGERPRINT_SERVICE名称关联起来(估计到ServiceManager又是一个hashmap)
3.2 启用SystemServerInitThreadPool进行一些初始化工作,这里工作主要是获取biometricFingerrprint的HIDL服务,注意使用这个线程池的时间是有限制的.
这个线程池在SystemService.java中被大量使用

继续看3.1
>>
>>
至此,将FingeprrintService注册到serviceManager工作全部完成,这样其他service或者app就能通过ServiceManager.getService(name)来获取到FingerprintService服务对象了, 也就是前面的步骤2.4


三.综上
FingerprintService的实现流程
1.定义一个具体的类FingerprintManager,实现向app提供的fingerprint服务
frameworks\base\core\java\android\hardware\fingerprint\FingerprintManager.java

2.定义一个AIDL接口文件IFingerprintService,实现系统服务接口
frameworks\base\core\java\android\hardware\fingerprint\FingerprintService.aidl

3.定义一个类FingerprintService,作为SystemService的派生类.
frameworks\base\services\core\java\com\android\server\fingerprint\FingerprintService.java
这个类派生自抽象类SystemService,并重载了onStart()等抽象方法
frameworks\base\services\core\java\com\android\server\SystemService.java

4.在FingerprintService中定义一个内部类FingerprintServiceWrapper,实现步骤2定义的系统服务接口
frameworks\base\services\core\java\com\android\server\fingerprint\FingerprintService.java

5.将FingerprintServiceWrapper添加到系统服务.
frameworks\base\services\core\java\com\android\server\fingerprint\FingerprintService.java
注:部分这类服务是在 frameworks/base/services/java/com/android/server/SystemServer.java中被添加的

6.启动FingerprintService,实际上是调用到SystemService的onStart()方法,执行步骤5的操作
frameworks\base\services\java\com\android\server\SystemServer.java

7.在context中定义一个代表fingerprint的字符串
frameworks\base\core\java\android\content\Context.java

8.在SystemServiceRegistry中通过代理链接到FingerprintService,这样FingerprintManager的接口实现中就可以调用到IFingerprintService的接口
frameworks\base\core\java\android\app\SystemServiceRegistry.java

9.在SystemServiceRegistry中添加FingerprintManager实例化过程
frameworks\base\core\java\android\app\SystemServiceRegistry.java

10.在应用中使用FingerprintManager接口
frameworks\base\packages\SystemUI\src\com\android\keyguard\KeyguardUpdateMonitor.java

11.为保证编译通过,需要将AIDL添加至编译
frameworks\base\Android.mk
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值