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); } }
相关文章推荐
- 深入解读Android的内部进程通信接口AIDL
- ipc通道入侵相关命令整理
- Linux IPC命令的用法详解
- Linux进程通信(IPC)方式简介
- Android应用程序四大组件之使用AIDL如何实现跨进程调用Service
- 使用Android studio创建的AIDL编译时找不到自定义类的解决办法
- Android AIDL和远程Service调用示例代码
- Android中如何利用AIDL机制调用远程服务
- 基于Android AIDL进程间通信接口使用介绍
- Android 使用【AIDL】调用外部服务的解决方法
- Android程序设计之AIDL实例详解
- 实例讲解Android中的AIDL内部进程通信接口使用
- 浅谈Android Aidl 通讯机制
- Linux进程间通信(IPC)方式总结
- Android AIDL 原理解析
- Android IPC 机制【1】--简介
- 序列化接口:Serializable 、Parcelable
- Android 跨进程通信基础
- ipc$ 安全