今天要在《在Android系统中实现AIDL接口回调》这篇文章的基础上实现AIDL自定义对象的传递功能。还是上一篇说到的三个项目:
├── SimpleJar
├── SimpleJarClient
└── SimpleJarService
一、在SimpleJar项目中添加aidl中要传递的对象StudentInfo.aidl跟StudentInfo.java,具体如下:
├── Android.mk
└── src
└── com
└── china
└── jar
├── IVoiceCallBackInterface.aidl
├── IVoiceClientInterface.aidl
├── StudentInfo.aidl
├── StudentInfo.java
├── VoiceChangedListener.java
└── VoiceManager.java
StudentInfo.aidl跟StudentInfo.java的代码实现如下:
package com.china.jar;
parcelable StudentInfo;
package com.china.jar;
import android.os.Parcel;
import android.os.Parcelable;
public class StudentInfo implements Parcelable{
String name;
int age;
protected StudentInfo(Parcel in){
name = in.readString();
age = in.readInt();
}
public StudentInfo(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
public static final Creator<StudentInfo> CREATOR = new Creator<StudentInfo>() {
@Override
public StudentInfo createFromParcel(Parcel in) {
return new StudentInfo(in);
}
@Override
public StudentInfo[] newArray(int size) {
return new StudentInfo[size];
}
};
}
由于是跨进程之间的通信,所以传递对象需要序列化,让StudentInfo实现Parcelable。这样就可以在IVoiceClientInterface.aidl中使用StudentInfo对象进行数据传递了,如下:
package com.china.jar;
import com.china.jar.IVoiceCallBackInterface;
import com.china.jar.StudentInfo;
interface IVoiceClientInterface{
void face();
void registerCallBack(IVoiceCallBackInterface callback);
void unRegisterCallBack(IVoiceCallBackInterface callback);
void registerUser(in StudentInfo studentInfo);
}
二、在SimpleJarService项目的SimpleService.java类中实现 registerUser(in StudentInfo studentInfo)方法,具体实现如下:
├── AndroidManifest.xml
├── Android.mk
├── libs
│ ├── android-support-v4.jar
│ ├── fw.jar
│ └── simple.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ ├── values
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── values-v11
│ │ └── styles.xml
│ └── values-v14
│ └── styles.xml
└── src
└── com
└── china
└── service
├── BootReceiverBroadcast.java
├── Logger.java
├── SimpleControl.java
└── SimpleService.java
package com.china.service;
import com.china.jar.IVoiceCallBackInterface;
import com.china.jar.IVoiceClientInterface;
import com.china.jar.StudentInfo;
import com.china.jar.VoiceChangedListener;
import com.china.jar.VoiceManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
public class SimpleService extends Service{
private static VoiceClientInterfaceImpl mBinder;
@Override
public IBinder onBind(Intent intent) {
Logger.d();
return mBinder;//跟客户端绑定
}
@Override
public void onCreate() {
super.onCreate();
Logger.d();
if (null == mBinder){
initService();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Logger.d();
if (null == mBinder){
initService();
}
return START_STICKY;
}
//实现AIDL的接口
private class VoiceClientInterfaceImpl extends IVoiceClientInterface.Stub{
protected RemoteCallbackList<IVoiceCallBackInterface> mRemoteCallbackList =
new RemoteCallbackList<IVoiceCallBackInterface>();
private SimpleControl control;
public VoiceClientInterfaceImpl(){
control = new SimpleControl(voiceChangedListener);
}
@Override
public void face() throws RemoteException {
Logger.d("face----excute!");//客户端调用face方法时这里会执行,会打印face----excute!
}
//注册回调
@Override
public void registerCallBack(IVoiceCallBackInterface arg0)
throws RemoteException {
Logger.d();
mRemoteCallbackList.register(arg0);
}
//注销回调
@Override
public void unRegisterCallBack(IVoiceCallBackInterface arg0)
throws RemoteException {
Logger.d();
mRemoteCallbackList.unregister(arg0);
}
//调用回调方法
private VoiceChangedListener voiceChangedListener = new VoiceChangedListener() {
@Override
public void openAppByVoice(String arg0) {
Logger.d("arg0 = " + arg0);
int len = mRemoteCallbackList.beginBroadcast();
for (int i = 0; i <len; i++) {
try {
mRemoteCallbackList.getBroadcastItem(i).openAppByVoice(arg0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
mRemoteCallbackList.finishBroadcast();
}
};
@Override
public void registerUser(StudentInfo studentInfo) throws RemoteException {
Logger.d("name = " + studentInfo.getName() + " ,age = " + studentInfo.getAge());
}
}
//初始化服务,主要是向系统注册服务
private void initService(){
Logger.d();
if (null == mBinder){
synchronized (SimpleService.class) {
if (null == mBinder){
try {
mBinder = new VoiceClientInterfaceImpl();
ServiceManager.addService(VoiceManager.NAME, mBinder);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
registerUser(in StudentInfo studentInfo)方法体中实现非常简单,就是打印学生姓名跟年龄。
三、在SimpleJarClient项目中调用registerUser(in StudentInfo studentInfo)方法,进行自定义对象的数据传递,如下:
├── AndroidManifest.xml
├── Android.mk
├── libs
│ └── simple.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── activity_main.xml
│ │ ├── activity_tss.xml
│ │ ├── test.xml
│ │ ├── usb.xml
│ │ └── version.xml
│ ├── menu
│ ├── values
│ │ ├── dimens.xml
│ │ └── strings.xml
│ ├── values-v11
│ ├── values-v14
│ └── values-w820dp
│ └── dimens.xml
└── src
└── com
└── example
└── helloworld
├── TestVoice.java
├── UsbTest.java
└── util
├── Logger.java
└── USBUtil.java
package com.example.helloworld;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.china.jar.StudentInfo;
import com.china.jar.VoiceChangedListener;
import com.china.jar.VoiceManager;
import com.example.helloworld.util.Logger;
public class TestVoice extends Activity{
VoiceManager voiceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.version);
voiceManager = VoiceManager.getInstance();
if (voiceManager != null){
voiceManager.addVoiceChangedListener(new VoiceChangedListener() {//客户端的监听及实现
@Override
public void openAppByVoice(String arg0) {
Logger.d("packageName = " + arg0);
}
});
}
voiceManager.registerUser(new StudentInfo("赵敏", 18));//aidl中客户端传递自定义对象StudentInfo到服务端
}
public void startVoice(View view){
Logger.d();
Intent intent = new Intent();
intent.setClass(TestVoice.this, UsbTest.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
public void stopVoice(View view){
Logger.d();
VoiceManager.getInstance().face();
}
public void finishVoice(View view){
Logger.d();
finish();
}
}
四、运行结果如下:
代码参考路径:https://github.com/gunder1129/android-tool/tree/master/AIDLdemo