本次测试的是客户端和服务端使用Aidl方式实现跨进程通信。
准备工作:
1.首先定义一个客户端,这边是App0429(com.example.app0429),主要含有一个MainActivity.class
2.然后定义一个服务端,这边是App0423(com.example.app0423),主要写一个服务TestService.class
3.编写aidl文件
这边写了两个Bean类和三个aidl文件:
DemoSonBean.java
package aidl.connect;
import android.os.Parcel;
import android.os.Parcelable;
public class DemoSonBean implements Parcelable {
private String sonName;
private int sonCode;
protected DemoSonBean(Parcel in) {
sonName = in.readString();
sonCode = in.readInt();
}
public static final Creator<DemoSonBean> CREATOR = new Creator<DemoSonBean>() {
@Override
public DemoSonBean createFromParcel(Parcel in) {
return new DemoSonBean(in);
}
@Override
public DemoSonBean[] newArray(int size) {
return new DemoSonBean[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(sonName);
dest.writeInt(sonCode);
}
public String getSonName() {
return sonName;
}
public void setSonName(String sonName) {
this.sonName = sonName;
}
public int getSonCode() {
return sonCode;
}
public void setSonCode(int sonCode) {
this.sonCode = sonCode;
}
}
DemoSonBean.aidl:
// DemoSonBean.aidl
package aidl.connect;
// Declare any non-default types here with import statements
parcelable DemoSonBean;
DemoBean.java
package aidl.connect;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.List;
public class DemoBean implements Parcelable {
private String name;
private int code;
private List<String> ss;
private byte[] bArray;
private List<DemoSonBean> sons;
protected DemoBean(Parcel in) {
name = in.readString();
code = in.readInt();
ss = in.createStringArrayList();
bArray = in.createByteArray();
sons = in.createTypedArrayList(DemoSonBean.CREATOR);
}
public static final Creator<DemoBean> CREATOR = new Creator<DemoBean>() {
@Override
public DemoBean createFromParcel(Parcel in) {
return new DemoBean(in);
}
@Override
public DemoBean[] newArray(int size) {
return new DemoBean[size];
}
};
public byte[] getbArray() {
return bArray;
}
public void setbArray(byte[] bArray) {
this.bArray = bArray;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public List<String> getSs() {
return ss;
}
public void setSs(List<String> ss) {
this.ss = ss;
}
public List<DemoSonBean> getSons() {
return sons;
}
public void setSons(List<DemoSonBean> sons) {
this.sons = sons;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(code);
dest.writeStringList(ss);
dest.writeByteArray(bArray);
dest.writeTypedList(sons);
}
}
DemoBean.aidl
// DemoBean.aidl
package aidl.connect;
// Declare any non-default types here with import statements
parcelable DemoBean;
parcelable DemoSonBean;
写完aidl文件记得一定要编译一次,不然找不到方法,而且要保持客服端和服务端aidl下的文件一样,包名一致(最好是拷贝过去)
IVideo.aidl(这里定义的是无返回类型的方法,需要服务端处理后返回数据,可以定义返回类型的方法)
// IVideo.aidl
package aidl.connect;
// Declare any non-default types here with import statements
import aidl.connect.DemoBean;
import aidl.connect.DemoSonBean;
interface IVideo {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt,String aString);
void getDemoBean(in DemoBean bean);
void getDemoSonBean(in DemoSonBean bean);
}
然后服务端编写:
package com.example.app0423;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import androidx.annotation.Nullable;
import aidl.connect.DemoBean;
import aidl.connect.DemoSonBean;
import aidl.connect.IVideo;
public class TestService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return ibider;
}
private IBinder ibider = new IVideo.Stub() {
@Override
public void basicTypes(int anInt, String aString) throws RemoteException {
//這是基本數據類型測試
System.out.println("AIDL+++++"+"Service:"+"basicTypes"+aString);
}
@Override
public void getDemoBean(DemoBean bean) throws RemoteException {
//這是帶序列化對象的集合的序列化類型測試
//這裏服務端的處理只是打印 如果需要數據處理後返回給客戶端 可以定義函數為帶返回值類型
System.out.println("AIDL+++++"+"Service:"+"getDemoBean"+bean.getName()+":"+bean.getSons().get(0).getSonName());
}
@Override
public void getDemoSonBean(DemoSonBean bean) throws RemoteException {
//這是序列化數據類型測試
System.out.println("AIDL+++++"+"Service:"+"getDemoSonBean"+bean.getSonName());
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}
客户端:
package com.example.app0429;
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.Parcel;
import android.os.RemoteException;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
import aidl.connect.DemoBean;
import aidl.connect.DemoSonBean;
import aidl.connect.IVideo;
public class MainActivity extends AppCompatActivity {
private TextView send_tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
send_tv = findViewById(R.id.send_tv);
send_tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (iVideo!=null) {
try {
iVideo.basicTypes(0,"你好,Service,我hiActivity!");
DemoSonBean bean = new DemoSonBean();
bean.setSonName("SonName:jiajia");
bean.setSonCode(123);
iVideo.getDemoSonBean(bean);
DemoBean demoBean = new DemoBean();
demoBean.setName("Name:haha");
demoBean.setCode(001);
List<DemoSonBean> sonBeans = new ArrayList<>();
sonBeans.add(bean);
demoBean.setSons(sonBeans);
iVideo.getDemoBean(demoBean);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
Intent intent = new Intent("com.example.app0423.con_action");
intent.setPackage("com.example.app0423");
boolean result = this.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
System.out.println("bindService result: " + result);
}
private IVideo iVideo;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iVideo = IVideo.Stub.asInterface(service);
System.out.println("AIDL+++++"+"Main:链接Service成功");
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("AIDL+++++"+"Main:链接Service失败");
}
};
}
测试结果输出:
如果编译有问题记得在app下的build.gradle下的android{}中加入:
sourceSets {
main{
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/aidl']
resources.srcDirs = ['src/main/java', 'src/main/aidl']
aidl.srcDirs = ['src/main/aidl']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
}
github项目地址:
服务端:https://github.com/iStride17/Server_aidl