概述
1.Binder
1.1简介
Binder是一种进程间通信的机。Binder就是Android中的血管,在Android中我们使用Activity,Service等组件都需要 和AMS (system_server)进行通信,这种跨进程的通信都是通过Binder完成。
Activity,Service等组件和AMS不是同一个进程,其实也是多进程通信。
1.2性能
Binder 相对于传统的 Socket 方式,更加高效。
Binder数据拷贝只需要一次,而管道、消息队列、 Socket 都需要 2 次,共享内存 方式一次内存拷贝都不需要,但实现方式又比较复杂。
1.3安全
传统的进程通信方式对于通信双方的身份并没有做出严格的验证,比如 Socket 通 信的 IP 地址是客户端手动填入,很容易进行伪造。
Binder 机制从协议本身就支持对通信双方做身份校检,从而大大提升了安全性。
2.AIDL
2.1简介
AIDL ( Android 接口定义语言),可以使用它定义客户端与服务端进程间通信( IPC )的编程接口。在 Android系统中,每个进程都运行在一块独立的内存中, 在 其中完成自己的各项活动,与其他进程都分 隔开来。可是有时候我们又有应用 间进行互动的需求,比较传递数据或者任务委托等,AIDL 就是为了满足这种需求 而诞生的。通过AIDL ,可以在一个进程中获取另一个进程的数据和调用其暴露出 来的方法,从而满足进程间通信的需求。
AIDL 是用于定义服务端和客户端通信接口的一种描述语言,可以拿来生产 IPC 代 码,从某种意义上说
AIDL 其实就是一个模板,因为在使用过程中,实际起作用的并不是 AIDL 文件, 而是据此生产的一个Interface的实例代码, AIDL 其实是为了避免我们重复写代码 而出现的一个模板。
2.2 创建.aildl 文件
系统会自动生产文件夹和aidl文件
2.3 具体的业务对象实现基于 .aidl 文件生成的接口
然后build一下
2.4 向客户端公开接口
创建一个service公开接口
package com.hp.server;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class PayService extends Service {
public PayService() {
}
@Override
public IBinder onBind(Intent intent) {
return new IPayImpl();
}
public class IPayImpl extends IPayAidlInterface.Stub{
private String account;
private int money;
@Override
public void setAccount(String account) throws RemoteException {
this.account=account;
}
@Override
public void steMoney(int money) throws RemoteException {
//打开Activity
Intent intent=new Intent();
intent.setClass(PayService.this,MainActivity.class);
//新的 task中打开
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("money",money);
startActivity(intent);
this.money=money;
}
@Override
public String getInfo() throws RemoteException {
return "账号是:"+account+"转账金额是:"+money+"转账成功!!!";
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
}
}
2.5 客户端远程调用
创建另一个项目进行测试,首先创建aidl文件夹
在项目所在系统根路径位置中将服务端的aidl文件夹下的.aidl文件连包一起复制粘贴在客户端的main文件夹所在位置的文件夹下。
然后服务端再build一下,此时就可以具体调用了,具体实现参考如下:
package com.hp.server;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.hp.client.R;
public class MainActivity extends AppCompatActivity {
private Button btn_start,btn_stop,btn_call;
private IPayAidlInterface iPayAidlInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start=findViewById(R.id.btn_start);
btn_stop=findViewById(R.id.btn_stop);
btn_call=findViewById(R.id.btn_call);
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i("跟Server进行通信","绑定服务");
Intent intent=new Intent();
intent.setComponent(new ComponentName("com.hp.server","com.hp.server.PayService"));
bindService(intent,conn,BIND_AUTO_CREATE);
}
});
btn_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
unbindService(conn);
}
});
btn_call.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
iPayAidlInterface.setAccount("x12369");
iPayAidlInterface.steMoney(100);
String info = iPayAidlInterface.getInfo();
Log.i("跟Server进行通信",info);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
iPayAidlInterface=IPayAidlInterface.Stub.asInterface(service);
Log.i("跟Server进行通信",iPayAidlInterface+"");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
}
注:google增加了软件包可见性的限制,targetSdk 版本为30的时候,在Android11 的机型上,AIDL完全不可用,服务也连接不上,但是在低版本的手机上,或者targetSdk 29时候可以用。
在客户端清单文件中加上如下代码即可:
<queries>
<package android:name="com.wpw.server" />
</queries>
总结:
AIDL是什么?
Android 通信接口定义语言
AIDL用在哪?
进程间通信
如果现在想要进行进程间通信,应该如何操作?
服务端应该做什么?
1. 定义.aidl文件,定义具体业务的抽象方法 2. 将项目rebuild,系统会自动生成和.aidl文件同名的java文件 3. 创建新的类,让类继承 接口.Stub 4. 向客户端公开接口,依托于服务客户端做什么?
1. 将服务器的.aidl连包一起放入客户端,将项目rebuild 2. 在Activity中绑定服务 1. 在绑定服务的过程中,发现无法对服务器公开的接口进行连接(API 30)在AndroidManifest.xml 添加
``` <querys> <package android:name="com.hopu.server" /> </querys> ```
绑定服务后,跟服务器开始进行对话
最后
以上就是甜美路人为你收集整理的Android中的Binder和AIDL的全部内容,希望文章能够帮你解决Android中的Binder和AIDL所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复