AIDL简单实例

Binder是Android中的一个类,它实现了一个IBinder接口,是Android中跨进程的通信方式,是ServiceManager链接各种Manager(ActivityManager,WindowManager),从Android应用层来说,Binder是客户端和服务端进行通信的桥梁。我们从AIDL来分析Binder工作机制。

创建步骤如下:

一.创建AIDL工程创建IMyAidl.aidl和Person.aidl类

// IMyAidl.aidl
package com.example.cmj.ipc;
import com.example.cmj.ipc.bean.Person;
interface IMyAidl {
void addPerson(in Person person);
    List<Person> getPersonList();
}

// Person.aidl package com.example.cmj.ipc.bean; parcelable Person;

二.创建Person.java类
package com.example.cmj.ipc.bean;
import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {
private String mName;

public Person(String name) {
mName = name;
}

protected Person(Parcel in) {
mName = in.readString();
}

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

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

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

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mName);
}

@Override
public String toString() {
return "Person{" +
"mName='" + mName + '\'' +
'}';
}
}

三.make project生成IMyAidl.java文件

package com.example.cmj.ipc;
// Declare any non-default types here with import statements

public interface IMyAidl extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.cmj.ipc.IMyAidl
{
private static final java.lang.String DESCRIPTOR = "com.example.cmj.ipc.IMyAidl";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.example.cmj.ipc.IMyAidl interface,
 * generating a proxy if needed.
 */
public static com.example.cmj.ipc.IMyAidl asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.cmj.ipc.IMyAidl))) {
return ((com.example.cmj.ipc.IMyAidl)iin);
}
return new com.example.cmj.ipc.IMyAidl.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_addPerson:
{
data.enforceInterface(DESCRIPTOR);
com.example.cmj.ipc.bean.Person _arg0;
if ((0!=data.readInt())) {
_arg0 = com.example.cmj.ipc.bean.Person.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.addPerson(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getPersonList:
{
data.enforceInterface(DESCRIPTOR);
java.util.List<com.example.cmj.ipc.bean.Person> _result = this.getPersonList();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.cmj.ipc.IMyAidl
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public void addPerson(com.example.cmj.ipc.bean.Person person) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((person!=null)) {
_data.writeInt(1);
person.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public java.util.List<com.example.cmj.ipc.bean.Person> getPersonList() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<com.example.cmj.ipc.bean.Person> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getPersonList, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArrayList(com.example.cmj.ipc.bean.Person.CREATOR);
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_addPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getPersonList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void addPerson(com.example.cmj.ipc.bean.Person person) throws android.os.RemoteException;
public java.util.List<com.example.cmj.ipc.bean.Person> getPersonList() throws android.os.RemoteException;
}
四.生成客户端MyServiceActivity.java
 
public class MyServiceActivity extends AppCompatActivity {

private Button mBtn;
private List<Person> mPersonList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_service);
mBtn = findViewById(R.id.btn);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent1 = new Intent(getApplicationContext(), MyAidlService.class);
bindService(intent1, mConnection, BIND_AUTO_CREATE);
//addPerson();

}
});
}

private void addPerson() {
Random random = new Random();
Person person = new Person("shixin" + random.nextInt(10));
try {
mIMyAidl.addPerson(person);
mPersonList = mIMyAidl.getPersonList();
} catch (RemoteException e) {
e.printStackTrace();
}
}

private IMyAidl mIMyAidl;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//连接后拿到 Binder,转换成 AIDL,在不同进程会返回个代理
mIMyAidl = IMyAidl.Stub.asInterface(service);
try {
List<Person> personList = mIMyAidl.getPersonList();
Log.d("aidl",personList.toString());
} catch (RemoteException e) {
e.printStackTrace();
}

}

@Override
public void onServiceDisconnected(ComponentName name) {
mIMyAidl = null;

}
};
}
五.生成服务端
public class MyAidlService extends Service {
private ArrayList<Person> mPersons = new ArrayList<>();

@Override
public void onCreate() {
super.onCreate();
mPersons.add(new Person("cmj"));
}

/**
* 创建生成本地Binder对象
*/
private IBinder mIBinder = new IMyAidl.Stub() {
@Override
public void addPerson(Person person) throws RemoteException {
mPersons.add(person);

}

@Override
public List<Person> getPersonList() throws RemoteException {
return mPersons;
}
};

/**
* 客户端与服务端绑定时的回调,返回 mIBinder 后客户端就可以通过它远程调用服务端的方法,即实现了通讯
*
* @param intent
* @return
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {


return mIBinder;
}
}
我们进一步分析IMyAidl.java文件
1.DESCRIPTION:
Binder的唯一标识,例如:com.example.cmj.ipc.IMyAidl
2.asInterface(android.os.IBinder obj)
用于获取服务端Binder对象转换成客户端所需的AIDL接口类型的对象,这种转换过程是区分进程的,如果客户端和服务端在同一个进程,那么返回服务端Stub对象本身,否则是Stub.Proxy对象。
3.asBinder
返回当前Binder对象
4.onTransact
此方法运行在服务端,当客户端发起请求会通过系统底层封装后交由此方法来处理,服务端通过code可以确定客户端请求的方法,接着从data取出数据,执行完毕就向reply写入返回值。
5.Proxy.getBookList
输入类型Parcel对象_data,输出类型Parcel对象_reply和返回值对象List;然后把信息写入_data,接着调用transact方法发起RPC请求,服务端onTransact会被调用,直到RPC返回结果,从_reply取出RPC过程结果,最后返回_reply中的数据。
6.Proxy.addBook
没有返回值不需要从_reply取出返回值
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值