您的位置:首页 > 大数据 > 人工智能

AIDL简单实现(1)

2016-06-04 19:04 459 查看

1、服务端

服务端首先要创建一个Service用来监听客户端的连接请求,然后创建一个AIDL文件,将暴露给的客户端的接口在这个AIDL文件中声明,最后在Service中实现这个AIDL接口即可

2、客户端

客户端首先要绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转成AIDL接口所属的类型,接着就可以调用AIDL中的方法了。

3、AIDL接口创建

AIDL支持如下接口类型:

除去short以外的基本数据类型

String和CharSequence

List:只支持ArrayList,且内部的数据必须能够被AIDL支持

Map:只支持HashMap,里面的key和value必须都被AIDL支持

Parcelable:所有实现了这个接口的类(android提供的序列化接口)

AIDL接口文件本身

所以我们可以创建如下接口文件:

package com.wscq.myaidl.aidl;
import com.wscq.myaidl.aidl.Book;
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
}


其中book类不是AIDL支持的接口类型,所以需要自定义一个Book类,实现Parcelable接口

package com.wscq.myaidl.aidl;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {
public int bookId;
public String bookName;

public Book(int bookId, String bookName) {
this.bookId = bookId;
this.bookName = bookName;
}

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

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

public static final Parcelable.Creator<Book> CREATOR = new parcelable.Creator<Book>() {
public Book createFromParcel(Parcel in) {
return new Book(in);
}

public Book[] newArray(int size) {
return new Book[size];
}
};

private Book(Parcel in) {
bookId = in.readInt();
bookName = in.readString();
}

@Override
public String toString() {
return "Book [bookId=" + bookId + ", bookName=" + bookName + "]";
}

}


注意在每一个实现了Parcelable的接口类,都需要创建相应的AIDL文件去声明,如下代码所示:

package com.wscq.myaidl.aidl;
parcelable Book;


建议所有的AIDL文件都放到一个文件夹下,因为客户端和服务端都会用到此文件,这样可以方便复制

4、远程服务端Service的实现

package com.wscq.myaidl;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import com.wscq.myaidl.aidl.Book;
import com.wscq.myaidl.aidl.IBookManager;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;

public class BookManagerService extends Service {
private static final String TAG = "BMS";
/** 使用这个list的原因是他可以进行自动的线程同步,类似的还有ConcurrentHashMap */
private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<Book>();
private Binder mBinder = new IBookManager.Stub() {

@Override
public List<Book> getBookList() throws RemoteException {
return mBookList;
}

@Override
public void addBook(Book book) throws RemoteException {
mBookList.add(book);
}
};

public void onCreate() {
super.onCreate();
mBookList.add(new Book(1, "Android"));
mBookList.add(new Book(2, "Ios"));
}

public IBinder onBind(Intent intent) {
return mBinder;
}
}


需要在AndroidManfist中进行如下注册:

这里为了方便测试,所以Service和Activity处于一个程序中。所以需要用’android:process=”:remote” ‘这个标签,来让Service单独运行在一个线程中,这样可以模拟IPC通讯。

<service
android:name="com.wscq.myaidl.BookManagerService"
android:process=":remote" >
</service>


5、客户端的代码实现

package com.wscq.myaidl;
import java.util.List;
import com.wscq.myaidl.aidl.Book;
import com.wscq.myaidl.aidl.IBookManager;
import android.app.Activity;
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;
public class BookManagerActivity extends Activity {
private static final String TAG = "BookManagerActivity";
private ServiceConnection mConnection = new ServiceConnection() {
// 服务连接后
@Override
/**
* 服务连接以后执行此方法
*/
public void onServiceConnected(ComponentName name, IBinder service) {
// 通过Binder来传递bookManager
IBookManager bookManager = IBookManager.Stub.asInterface(service);
try {
List<Book> list = bookManager.getBookList();
// 获取返回的类型
// query book list, list type:java.util.ArrayList
Log.i(TAG, "query book list, list type:" + list.getClass().getCanonicalName());
// 获取书名
// quert book list: [Book [bookId=1, bookName=Android], Book
// [bookId=2, bookName=Ios]]
Log.i(TAG, "quert book list: " + list.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 通过intent来连接远程服务端,5.0以后必须使用显式意图,也就是必须使用全类名
Intent intent = new Intent(this, BookManagerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  aidl IPC 进程间通讯