「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」
前言:
Android中进程通信的方式主要有Socket,Binder本篇文章主要学习Binder的使用。
Android中开启多进程
在一个应用内开启多进程模式,我们只需要给四大组件(Activity、Service、Receiver、ContentProvider)在Menifest.xml中指定android:process属性,注意只能是四大组件。这也说明了我们无法给一个其他的类或者线程指定其运行时所在的进程
<activity
android:name="ProcessActivity"
android:process=":remote">
</activity>
<activity
android:name="ProcessActivity"
android:process="com.stxx.test.remote">
</activity>
这里给android:process赋值时,使用了两种不同的方式,第一种:remote代表了这是当前应用的私有进程,其他应用的组件不可以和它跑在同一进程中。而第二种不以“:”开头的进程属于全局进程,其他应用通过ShareUID方式可以和它跑在同一进程中。
关于ShareUID的解释: 在Android里面每个app都有一个唯一的(UID)linux user ID,而具有相同的UID才能共享数据,我们可以在menifest.xml中添加shareUid标签强行将多个应用使用相同的UID.这样我们就可以访问对方的数据。比如data/data目录下的文件,内存的数据
应用1
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
//指定uid
android:sharedUserId="com.stxx.uid"
package="com.gavindon.canvaspractice1">
应用2
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
//指定uid和应用1的相同
android:sharedUserId="com.stxx.uid"
package="com.gavindon.canvaspractice2">
多进来带来的问题
- 静态变量和单例模式完全失效
- 线程同步机制失效
- Application 会有几个进程就创建几次
默认一个应用是一个进程且会被分配一个虚拟机,而在这个应用上再开启一个进程的话,子进程也会分配一个虚拟机并且会继承父进程中的堆栈,(共享)内存等。参考Linux中父进程fork()子进程 ,由此可以理解上面多进程带来的问题!
Android中的Binder
Android系统中关于创建Window,Handler通信等等都是通过Binder和系统进行通信的。 Binder在Linux层是一个驱动,,在android framework来讲Binder是ServiceManager(ServiceManager是一个守护进程,它维护着系统服务和客户端的binder通讯,ServiceManager进程循环从Binder设备文件读取数据,然后解析数据,提供给Client,Service端进行查询)连接各种Manager和Service的桥梁。在应用层Binder是服务端和客户端通信的媒介。当客户端bindService()时。服务端会返回一个包含了服务端业务调用的Binder对象,通过Binder对象就可以获得服务端接口提供的数据。 android中提供的AIDL可以很方便的实现Binder.
AIDL的使用方法
- 使用Android studio 在项目上new 一个AIDL file.工具会自动创建一个AIDL的文件夹
- 声明一个接口,给客户端提供调用的方法
- 使用Bundle或者自定义一个实体类(实体类需要实现Parceable接口)因为数据是要在内存中传递的。
- 在菜单栏上Build->make project 则会在build-generated-aidl_source_output_dir目录下自动生成已经实现 android.os.IInterface接口的类,这个类中有两个重要的内部类Stub和Proxy Stub类继承了Binder,负责给外提供Binder对象和接口对象。 Proy类主要实现接口定义方法的实现逻辑
Stub类中有两个种要的方法
- asInterface 负责返回给客户端提供数据的接口对象
- onTransact 负责处理进程间通信的数据