0
点赞
收藏
分享

微信扫一扫

aidl使用采坑记

千妈小语 2022-09-07 阅读 65


什么是AIDL?

​AIDL​​是 ​​Android Interface definition language​​的缩写,它是一种​​Android​​内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口

AIDL可以解决什么问题?

  • 可以实现多个应用程序共享同一个Service的功能,比如:IM服务可以提供给多个APP使用,先在推送基本都是采取这种方案
  • 可以跨进程调用服务里的方法

搭建了简单的Service框架

1.继承Service

public class PushService extends Service{

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
}

2.在AndroidManifest.xml里注册

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="name.quanke.aidldemo">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name=".App"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<service
android:name=".PushService"
android:enabled="true"
android:process=":push"
android:exported="true">
</service>
</application>

</manifest>

建立AIDL

创建AIDL文件


aidl使用采坑记_客户端


编写AIDL文件

interface IHandler {
void connect();
}

aidl生成后的样子


aidl使用采坑记_客户端_02


编写客户端 ServiceConnection

public class PushClient {
private IHandler iHandler;
private static PushClient instance = new PushClient();

public static PushClient getInstance() {
return instance;
}

public void init(Application app){
Intent binderIntent = new Intent(app,PushService.class);
app.bindService(binderIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}

private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iHandler = IHandler.Stub.asInterface(service);
//连接成功调用
}

@Override
public void onServiceDisconnected(ComponentName name) {
//断开连接调用
}
};

//通过AIDL远程调用
public void connect(){
try {
iHandler.connect();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}


写服务端实现connect方法


public class LibHandler extends IHandler.Stub{


@Override
public void connect() throws RemoteException {

}

@Override
public IBinder asBinder() {
return null;
}
}


测试



public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}

private void init() {
findViewById(R.id.aidl_test).setOnClickListener(this);
}

@Override
public void onClick(View view) {
PushClient.getInstance().connect();
}
}


其实到这里我们就结束了。


接下来我们看看如果自定义传递的数据类型


传递自定义的类型

AIDL默认支持的类型包括Java基本类型(int、long、boolean等),和(String、List、Map、CharSequence),如果要传递自定义的类型需要实现android.os.Parcelable接口。




自定义Message实体:


public class Message implements Parcelable {
private long id;
private String content;

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

@Override
public String toString() {
return "Message{" +
"id=" + id +
", content='" + content + '\'' +
'}';
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.content);
}

protected Message(Parcel in) {
this.id = in.readLong();
this.content = in.readString();
}

public static final Creator<Message> CREATOR = new Creator<Message>() {
@Override
public Message createFromParcel(Parcel source) {
return new Message(source);
}

@Override
public Message[] newArray(int size) {
return new Message[size];
}
};

}


修改IHandler


interface IHandler {
void connect();
void sendMessage(Message message);
}




aidl使用采坑记_android_03


注意: 自定类型aidl文件名字、路径需要和自定义类名字、路径保持一致,


 编译一下,发现报了个错


aidl使用采坑记_ide_04


意思是必须定义Message的方向,AIDL 参数有方向。(学习了)

如果​​sendMessage​​方法的​​message​​参数是纯粹的输入参数—这意味着是从客户端到服务器的数据,你需要在AIDL声明:


void sendMessage(in Message message);

如果 ​​sendMessage​

方法的 ​​message​

参数是纯粹的输出-这意味着它的数据是通过从服务器到客户端,使用:


void sendMessage(out Message message);

如果 ​​sendMessage​

方法的 ​​message​

参数是输入也是输出-客户端的值在服务可能会修改,使用:

void sendMessage(inout Message message);

我们这里是客户端范围服务端的数据,所以用in

interface IHandler {
void connect();
void sendMessage(in Message message);
}


好了,aidl的用法就到这里了,aidl主要是用在跨进程间通信和数据交换,平时开发中也用的比较少,通过这个例子加深了对他的用法,后面有什么好的坑,我会发出了的,谢谢大家。最后做个链接 


​​https://github.com/xiangzhihong/aidl ​​


举报

相关推荐

0 条评论