上一篇中提到了 AIDL,这里把原来写过的一个例子贴在这里,供学习和备忘。
Android Interface Definition Language android内部进程通信接口的描述语言
这里把简单的例子贴到这里,
AIDL支持Java原始数据类型,AIDL还支持传递其他AIDL接口,但你引用的每个AIDL接口都需要一个import语句,即使位于同一个包中。
看到这个传递参数又想到了 android Intent中的 传递参数,(前面有些过,简单的类型都支持,如果需要传递自定义 entity 就需要继承 Parcelable)
1.先传递普通类型的
这个要在自己的 service端 和 客户端 都定义1个 XXX.aidl 文件,(这个就是 通信的标准啦)
里面其实就是1个定义的接口
package com.example.aidl;
interface AIDLTest { // 这个简单类型以 String 为例
String AIDL_test(String name);
}
2.如果要传递自定义的 对象,和对象数组的话
首先定义自己的类的文件,去实现 Parcelable接口,这个前面我有写过了,再为这个类声明1个aidl, entity.aidl 告诉系统要序列化谁 。
Entity
//传递这个实体类
public class Entity implements Parcelable {
public String name;
public int age;
public static final Parcelable.Creator<Entity> CREATOR = new Parcelable.Creator<Entity>() {
@Override
public Entity createFromParcel(Parcel parcel) {
Entity app= new Entity();
app.name = parcel.readString();
app.age = parcel.readInt();
return app;
}
@Override
public Entity[] newArray(int size) {
return new Entity[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
}
Entity.aidl
package com.example.aidl;
parcelable Entity;
EntityTest.aidl (参数是自己定义的对象)
非原始类型中,需要一个方向指示符。方向指示符包括in、out、和inout。in由客户端,out表示由服务端,inout表示客户端和服务端都设置了该值。
package com.example.aidl;
import com.example.aidl.Entity;
interface EntityTest {
String EntityTest(in Entity entity);
}
service端的设置(别人会通过这个action绑定到它)
<service android:name="com.example.serviceaa.AIDLService">
<intent-filter>
<action android:name="android.intent.action.TestAIDL" />
</intent-filter>
</service>
public class MainActivity extends Activity {
private Button bangding;
private Button aidl_button;
private AIDLTest aidlTest; //简单传递String aidl
private EntityTest entityTest; //传递对象 aidl
//链接远程aidl service
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// asInterface就强制 转化成 AIDLTest 类型了
// aidlTest = AIDLTest.Stub.asInterface(service);
//传递对象
entityTest = EntityTest.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定
bangding = (Button) findViewById(R.id.button1);
bangding.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("android.intent.action.TestAIDL");
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
});
//hello
aidl_button = (Button) findViewById(R.id.button2);
aidl_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
/**
* 1. 调用 远程 得到 返回的 back_string String
*/
// String back_string = aidlTest.AIDL_test(" this is aidl ");
// Toast.makeText(MainActivity.this, back_string, Toast.LENGTH_SHORT).show();
/**
* 2.传递对象
*/
Entity en = new Entity();
en.name = "json";
en.age = 315;
String entity_back = entityTest.EntityTest(en);
Toast.makeText(MainActivity.this, "entity_back = "+ entity_back, Toast.LENGTH_SHORT).show();
}catch (RemoteException e) {
Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show();
}
}
});
}
}
service端:
public class AIDLService extends Service{
/**这个Stub它继承了Binder。
* Stub继承android.os.Binder类并实现IPerson接口,比较重要的方法是asInterface(IBinder)方法,
* 该方法会将IBinder类型的对象转换成 你的类的对象 类型,必要的时候生成一个代理对象返回结果。
*/
private static final String TAG = "AIDLService";
//1.传递String
// AIDLTest.Stub stub = new AIDLTest.Stub() {
// @Override
// public String AIDL_test(String name) throws RemoteException {
// System.out.println("AIDL_test+ name = "+ name );
// return "AIDL_test, " + name;
// }
// };
//2.传递 entity
EntityTest.Stub stub = new EntityTest.Stub(){
@Override
public String EntityTest(com.example.aidl.Entity entity)
throws RemoteException {
String back_string = "hello, " + entity.name;
return back_string;
}
};
@Override
public IBinder onBind(Intent intent) {
System.out.println("== onBind()");
return stub;
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("== onUnbind()");
return true;
}
@Override
public void onDestroy() {
System.out.println("== onDestroy()");
super.onDestroy();
}
}
经过测试都是可以的。