注册服务
在Native层的服务注册,我们选择以media为例来展开讲解。
Media服务注册的过程涉及到MediaPlayerService(作为Client进程)和Service Manager(作为Service进程),通信流程图如下所示:
流程图
##Java 注解和反射与动态代理
在定义注解时,注解类也能够使用其他的注解声明。对注解类型进行注解的注解类,我们称之为 metaannotation(元注解)。一般的,我们在定义自定义注解时,需要指定的元注解有两个 :
在定义注解时,注解类也能够使用其他的注解声明。对注解类型进行注解的注解类,我们称之为 >metaannotation(元注解)。一般的,我们在定义自定义注解时,需要指定的元注解有两个 :
@Target
注解标记另一个注解,以限制可以应用注解的 Java 元素类型。目标注解指定以下元素类型之一作为其值:
- ElementType.ANNOTATION_TYPE 可以应用于注解类型。
- ElementType.CONSTRUCTOR 可以应用于构造函数。
- ElementType.FIELD 可以应用于字段或属性。
- ElementType.LOCAL_VARIABLE 可以应用于局部变量。
- ElementType.METHOD 可以应用于方法级注解。
- ElementType.PACKAGE 可以应用于包声明。
- ElementType.PARAMETER 可以应用于方法的参数。
- ElementType.TYPE 可以应用于类的任何元素。
@Retention
注解指定标记注解的存储方式:
- RetentionPolicy.SOURCE - 标记的注解仅保留在源级别中,并被编译器忽略。
- RetentionPolicy.CLASS - 标记的注解在编译时由编译器保留,但 Java 虚拟机(JVM)会忽略。
- RetentionPolicy.RUNTIME - 标记的注解由 JVM 保留,因此运行时环境可以使用它。
@Retention 三个值中 SOURCE < CLASS < RUNTIME,即CLASS包含了SOURCE,RUNTIME包含SOURCE、
CLASS。下文会介绍他们不同的应用场景。
举个栗子:
1 | // @Target(ElementType.TYPE)//只能在类上标记该注解 |
ServiceManager是Binder IPC通信过程中的守护进程,本身也是一个Binder服务,但并没有采用libbinder中的多线程模型来与Binder驱动通信,而是自行编写了binder.c直接和Binder驱动来通信,并且只有一个循环binder_loop来进行读取和处理事务,这样的好处是简单而高效。
ServiceManager本身工作相对简单,其功能:查询和注册服务。 对于Binder IPC通信过程中,其实更多的情形是BpBinder和BBinder之间的通信,比如ActivityManagerProxy和ActivityManagerService之间的通信等。
流程图
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
由于线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量,那么对于共享变量V,它们首先是在自己的工作内存,之后再同步到主内存。可是并不会及时的刷到主存中,而是会有一定时间差。很明显,这个时候线程 A 对变量 V 的操作对于线程 B 而言就不具备可见性了 。
**要解决共享对象可见性这个问题,我们可以使用volatile关键字或者是加锁(同步锁)**。
原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
可以把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步
可见性。对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。
volatile虽然能保证执行完及时把变量刷到主内存中,但对于count++这种非原子性、多指令的情况,由于线程切换,线程A刚把count=0加载到工作内存,线程B就可以开始工作了,这样就会导致线程A和B执行完的结果都是1,都写到主内存中,主内存的值还是1不是2
volatile关键字修饰的变量会存在一个“lock:”的前缀。
Lock前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线和高速缓存加锁,可以理解为CPU指令级的一种锁。
同时该指令会将当前处理器缓存行的数据直接写会到系统内存中,且这个写回内存的操作会使在其他CPU里缓存了该地址的数据无效。