Service与AIDL跨进程通信
1:
常见述语
方式一:
Messager
方式二:
AIDL
IPC
(Inter Process Communication)
可以实现安卓设备中进程之间的通信
Binder
Binder是Android的一个类,它实现了IBinder接口。
从IPC角度来说,Binder是Android中的一种跨进程通信方式。
通过这个Binder对象,客户端就可以获取服务端提供的服务或数据,这里的服务包括普通服务和基于AIDL的服务。
定义:Messenger是Google为我们封装好的简洁版的AIDL
AIDL,全称是Android Interface Define Language
定义:AIDL是实现安卓设备中进程间通信的安卓接口定义语言
2:
AIDL-应用(服务器端)
方式一:
Messager
方式二:
AIDL
1、将as切换到Project下,按照如图所示创建文件夹命名为aidl,在aidl文件夹下创建aidl文件,命名为IMyAidlInterface.aidl
2、修改aidl文件,提供一个方法,该方法 就是处理客户端的请求
3、rebuild project之后会发现自动生成一个Java文件:IMyAidlInterface.java
在服务端中新建一个类,继承Service,在其中定义一个IBinder类型的变量iBinder,引用上述接口IMyAidlInterface.java类中的Stub类对象,实现其中的add方法,在Service的onBind方法中,返回iBinder变量。
1.将as切换到Project下,按照如图所示创建文件夹命名为aidl,在aidl文件夹下创建aidl文件,命名为IMyAidlInterface.aidl
2.修改aidl文件,提供一个方法,该方法 就是处理客户端的请求
3.rebuild project之后会发现自动生成一个Java文件:IMyAidlInterface.java
4.在服务端中新建一个类,继承Service,在其中定义一个IBinder类型的变量iBinder,引用上述接口IMyAidlInterface.java类中的Stub类对象,实现其中的add方法,在Service的onBind方法中,返回iBinder变量。最终代码如下:
public class ServerService extends Service {
//TODO 代理人
IBinder binder=new IMyAidlInterface.Stub() {
@Override
public int add(int num1, int num2) throws RemoteException {
return num1+num2; }
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}}
5.清单文件中注册SErverService服务,在注册时应设置exported属性为true,保证该Service能被其他应用调用,否则会报
java.lang.SecurityException: Not allowed to bind to service Intent 异常。
3:Service-前台服务
方式一:
Messager
方式二:
AIDL
1.在客户端创建同样AIDL文件,要求包名AIDL名字必须一致,内容也必须一样提供add方法,rebuild 项目
2.Java代码,绑定服务调用服务器进程的方法
public class MainActivity extends AppCompatActivity {
IMyAidlInterface iMyAidlInterface;
//3.绑定服务回调
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//绑定服务成功后,返回服务端返回的binder,将其转成IMyAidlInterface调用add方法
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
int num=iMyAidlInterface.add(4,6);//调用服务端的add方法并得到结果
Toast.makeText(MainActivity.this, ""+num, Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
//解除绑定时调用, 清空接口,防止内容溢出
iMyAidlInterface=null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.绑定服务
Intent intent=new Intent();
intent.setAction("com.bawei.1609A");//设置action
intent.setPackage("com.example.aidl_server");//设置服务端应用进程包名
bindService(intent,connection, Service.BIND_AUTO_CREATE);}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection); }}
4:
Messager
方式一:
Messager
方式二:
AIDL
Messager的2个构造方法:分别以handler和Ibinder为参数 |
public Messenger(Handler target) { } |
public Messenger(IBinder target) { } |
我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。
核心代码
public class MainActivity extends AppCompatActivity {
//3.客户端的信使:负责接受服务器发来的消息
private Messenger Clientmesssager=new Messenger(new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle=msg.getData();
String message=bundle.getString("server_message");
Toast.makeText(MainActivity.this, "接受到服务器发来的消息"+message, Toast.LENGTH_SHORT).show();
}
});
// 4. 客户端发送消息给服务端
private Messenger Servermessenger;
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Servermessenger=new Messenger(service);//获取服务端信使
Message message=new Message();
message.replyTo= Servermessenger;
Bundle bundle=new Bundle();
bundle.putString("client_message","你好啊服务器");
message.setData(bundle);
try {
Servermessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace(); } }
//TODO 返回server_messager的代理人,便于客户端获取服务端信使
@Nullable
@Override
public IBinder onBind(Intent intent) {
return server_messager.getBinder();
}}
<service android:name=".MyService" android:exported="true">
<intent-filter>
<action android:name="com.bawei.1609A"></action>
</intent-filter>
</service>
public class MainActivity extends AppCompatActivity {
//3.客户端的信使:负责接受服务器发来的消息
private Messenger Clientmesssager=new Messenger(new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle=msg.getData();
String message=bundle.getString("server_message");
Toast.makeText(MainActivity.this, "接受到服务器发来的消息"+message, Toast.LENGTH_SHORT).show();
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Servermessenger=new Messenger(service);//获取服务端信使
Message message=new Message();
message.replyTo= Servermessenger;
Bundle bundle=new Bundle();
bundle.putString("client_message","你好啊服务器");
message.setData(bundle);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.绑定服务
Intent intent=new Intent();
intent.setAction("com.bawei.1609A");
intent.setPackage("com.example.messager_server");
bindService(intent,connection, Service.BIND_AUTO_CREATE);
}
//2.解除绑定
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}}
>