目录
1.3 Android系统中,涉及到多进程间的通信底层都是依赖于Binder IPC机制。
2.2.4生成与PayAidlInterfece.aidl一样的接口文件
2.2.8在AndroidManifest.xml中写上服务器的报名
1.Binder
1.1BInder是什么
1.机制:
Binder
是一种进程间通信的机制
2.驱动:
Binder
是一个虚拟物理设备驱动
3.应用层:
Binder
是一个能发起进程间通信的
JAVA
类
4.Binder
就是
Android
中的血管,在
Android
中我们使用
Activity,Service
等组件都需要和
AMS
(
system_server
)进行通信,这种跨进程的通信都是通过
Binder
完成。
5.Activity,Service
等组件和
AMS
不是同一个进程,其实也是多进程通信。
1.2为什么要用多进程
1.虚拟机给每一个进程分配的内存是有限制的
,LMK
会优先回收对系统资源占用多的进程
2.为了突破内存限制,防止占用内存过多被杀
3.功能稳定性,一个进程崩溃对另外进程不造成影响:将不稳定功能放入独立进程
4.规避内存泄漏,独立的
WebView
进程阻隔内存泄漏导致问题
1.3 Android系统中,涉及到多进程间的通信底层都是依赖于Binder IPC机制。
1.例如当进程
A
中的
Activity
要向进程
B
中的
Service
通信,这便需要依赖于
Binder IPC
。不仅于此,整 个Android
系统架构中,大量采用了
Binder
机制作为
IPC
(进程间通信,
Interprocess
Communication
)方案。
2.也存在部分其他的
IPC
方式,如管道、
SystemV
、
Socket
等
2.AIDL
2.1AIDL简介
2.1.1AIDL是什么?
Adroid通信接口定义语言
2.1.2AIDL用在哪?
进程间通信
AIDL
(
Android
接口定义语言),可以使用它定义客户端与服务端进程间通信(
IPC
)的编程接口。在 Android系统中,每个进程都运行在一块独立的内存中,在其中完成自己的各项活动,与其他进都分 隔开来。可是有时候我们又有应用间进行互动的需求,比较传递数据或者任务委托等,AIDL
就是为了满 足这种需求而诞生的。通过AIDL
,可以在一个进程中获取另一个进程的数据和调用其暴露出来的方法, 从而满足进程间通信的需求。
2.2AIDL的使用流程
2.2.1AIDL支持的数据类型,以及注意事件
在
AIDL
中可以通过可带参数以及返回值的一个或多个方法来声明接口,参数和返回值可以是任意类 型,AIDL
中支持的数据类型如下:
1.java
的
8
种数据类型:
byte
、
short
、
int
、
long
、
float
、
double
、
boolean
、
char
2.除此之外支持
String
、
charSequence
、
List
、
Map
3.自定义数据类型
如果参数或返回值类型为
List
或
Map
时:
List
中的所有元素都必须是
AIDL
支持的数据类型、其他
AIDL
生成的接口或自己声明的可打包类
型。可选择将
List
用作
“
通用
”
类(例如,
List
)。另一端实际接收的具体类始终是
ArrayList
,但生
成的方法使用的是
List
接口。
Map
中的所有元素都必须是
AIDL
支持的数据类型、其他
AIDL
生成的接口或您声明的可打包类
型。 不支持通用
Map
(如
Map<String,Integer>
形式的
Map
)。 另一端实际接收的具体类始终
是
HashMap
,但生成的方法使用的是
Map
接口。
2.2.2创建.aildi文件
2.2.3编辑PayAidlInterface.aidl
// PayAidlInterface.aidl
package com.hopu.day14_server;
// Declare any non-default types here with import statements
interface PayAidlInterface {
//这里是具体的业务
void setMoney(int money);
void setUser(String user);
String getInfo();
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
2.2.4生成与PayAidlInterfece.aidl一样的接口文件
只需要Build一下就行
2.2.5创建一个实体类Pay
1.继承PayAidlInterface.Stub
2.实现他的三个构造方法
public class Pay extends PayAidlInterface.Stub{
private String user;
private int money;
@Override
public void setMoney(int money) throws RemoteException {
this.money=money;
}
@Override
public void setUser(String user) throws RemoteException {
this.user=user;
}
@Override
public String getInfo() throws RemoteException {
return "账号是:"+user+",钱是:"+money;
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
}
}
2.2.6 向客户端公开接口
创建一个 Service 以便对外提供具体的业务
public class PayService extends Service {
public PayService() {
}
@Override
public IBinder onBind(Intent intent) {
return new Pay();
}
2.2.7 创建一个客户端
把服务端的.aidl的包复制过来,之后Build一下生成接口
2.2.8在AndroidManifest.xml中写上服务器的包名
<queries>
<package android:name="com.hopu.day14_server"/>
</queries>
2.2.9之后再Activity里进行操作
我这里创建了三个按钮,对应的是绑定,解绑(这个没有写),和对话
public class MainActivity extends AppCompatActivity {
private Button but_bind;
private Button but_unbind;
private Button but_cull;
private PayAidlInterface payAidlInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but_bind=findViewById(R.id.but_bing);
but_cull=findViewById(R.id.but_cull);
but_unbind=findViewById(R.id.but_unbing);
but_bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent();
intent.setComponent(new ComponentName("com.hopu.day14_server","com.hopu.day14_server.PayService"));
bindService(intent,conn,BIND_AUTO_CREATE);
Log.i("Activity","绑定成功");
}
});
but_unbind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
but_cull.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
payAidlInterface.setUser("123");
payAidlInterface.setMoney(10);
String info=payAidlInterface.getInfo();
Log.i("Activity",info);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
public ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
payAidlInterface=PayAidlInterface.Stub.asInterface(iBinder);
Log.i("Activity",payAidlInterface+"");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
}