文章目录
- 简述
- aidl文件
- 服务端的实现
- 客户端的实现
- 验证过程
简述
主要实现的是两个应用之间跨进程通信的过程,client端调用server端的具体实现,然后server端给client回调数据,详细如下所示
aidl文件
以下的文件需要在服务端与客户端都配置一份且保持一致
1.aidl 跨进程所需要的文件目录如下所示
以下文件是对应的TestDataBean.aidl文件的
2.IOnTestDataCallback.aidl文件,用于服务端给客户端回调接口,传递一个parcel类型的数据
// IOnTestDataCallback.aidl
package com.example.test;
import com.example.test.TestDataBean;
// Declare any non-default types here with import statements
interface IOnTestDataCallback {
void onCallback(in TestDataBean dataBean);
}
3.IOnTestDataListener.aidl文件,用于客户端给服务端请求数据的调用过程,oneway表示异步方法,不用等待方法中的实现执行完成,直接返回就行了。
// IOnTestDataListener.aidl
package com.example.test;
import com.example.test.IOnTestDataCallback;
// Declare any non-default types here with import statements
interface IOnTestDataListener {
oneway void sendData(String str, in byte[] bytes,in IOnTestDataCallback callback);
}
4.TestDataBean.aidl文件,用于跨进程传递parcel对象数据。
// TestDataBean.aidl
package com.example.test;
parcelable TestDataBean;
5.TestDataBean.java文件,TestDataBean.aidl中的具体实现方式。
package com.example.test;
import android.os.Parcel;
import android.os.Parcelable;
public class TestDataBean implements Parcelable {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
private String name;
private int number;
public TestDataBean() {
}
protected TestDataBean(Parcel in) {
name = in.readString();
number = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(number);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<TestDataBean> CREATOR = new Creator<TestDataBean>() {
@Override
public TestDataBean createFromParcel(Parcel in) {
return new TestDataBean(in);
}
@Override
public TestDataBean[] newArray(int size) {
return new TestDataBean[size];
}
};
}
服务端的实现
1.TestBinderService.java文件
package com.tencent.wemeet.testwhitelist;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.Nullable;
import com.example.test.IOnTestDataCallback;
import com.example.test.IOnTestDataListener;
import com.example.test.TestDataBean;
import java.util.Arrays;
public class TestBinderService extends Service {
private static final String TAG = "TestBinderService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new IOnTestDataListener.Stub() {
@Override
public void sendData(String str, byte[] bytes, IOnTestDataCallback callback) throws RemoteException {
Log.d(TAG, "str = " + str + ",bytes = " + Arrays.toString(bytes));
TestDataBean bean = new TestDataBean();
bean.setName("zhangsan");
bean.setNumber(20);
try {
Thread.sleep(5000);
callback.onCallback(bean);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
}
2.AndroidManifest.xml文件配置
<service
android:name=".TestBinderService"
android:exported="true">
<intent-filter>
<action android:name="com.binder.test.service" />
</intent-filter>
</service>
客户端的实现
TestBinderActivity.java文件
package com.example.test;
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 androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class TestBinderActivity extends AppCompatActivity {
public static final String TAG = "TestBinderActivity";
private boolean isBinder;
private IOnTestDataListener binder;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_binder_test);
Intent intent = new Intent();
intent.setAction("com.binder.test.service");
intent.setPackage("com.tencent.wemeet.testwhitelist");
isBinder = bindService(intent, connection, Context.BIND_AUTO_CREATE);
findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (binder == null) {
Log.d(TAG, "binder is null");
return;
}
Log.d(TAG, "begin");
try {
binder.sendData("123", new byte[]{1, 2, 3}, new IOnTestDataCallback.Stub() {
@Override
public void onCallback(TestDataBean dataBean) throws RemoteException {
Log.d(TAG, "name = " + dataBean.getName() + ",number = " + dataBean.getNumber());
}
});
} catch (RemoteException e) {
Log.d(TAG, "sendData RemoteException");
throw new RuntimeException(e);
}
Log.d(TAG, "end");
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (isBinder) {
isBinder = false;
unbindService(connection);
connection = null;
binder = null;
}
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected");
binder = IOnTestDataListener.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected");
}
};
}
验证过程
先打开server端相关的应用进程,之后再打开client端相关的应用进程,然后通过binder的方式连接server端并进行通信,记录大致的通信过程。