AIDL(Android Interface Definition Language ,Android 接口定义语言),定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。
只有允许不同应用的客户端用 IPC 方式访问服务,并且想要在服务中处理多线程时,才有必要使用 AIDL。
如果不需要执行跨越不同应用的并发 IPC,就应该通过实现一个 Binder 创建接口;或者,如果想执行 IPC,但根本不需要处理多线程,则使用 Messenger 类来实现接口。
1、创建 AIDL 文件
首先在 java 同级目录 aidl 文件夹,然后创建 .aidl 文件。
package com.wshunli.ipc.demo;import com.wshunli.ipc.demo.Book;interface IBookManager { List<Book> getBookList () ; void addBook (in Book book) ; void basicTypes (int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) ;}
在 .aidl 文件中支持的数据类型包括:
基本数据类型
String 和 CharSequence
List:只支持 ArrayList , 里面的元素都必须被 AIDL 支持
Map:只支持 HashMap , 里面的元素必须被 AIDL 支持
实现 Parcelable 接口的对象
所有 AIDL 接口
然后创建实现了 Parcelable 的类:
public class Book implements Parcelable { public String name; public Book (String name) { this .name = name; } @Override public int describeContents () { return 0 ; } @Override public void writeToParcel (Parcel dest, int flags) { dest.writeString(name); } public static Creator<Book> CREATOR = new Creator <Book>() { @Override public Book createFromParcel (Parcel source) { return new Book (source); } @Override public Book[] newArray(int size) { return new Book [size]; } }; private Book (Parcel source) { name = source.readString(); } @Override public String toString () { return "Book{" + "name='" + name + '\'' + '}' ; } }
创建 Book.aidl 文件:
package com.wshunli.ipc.demo;parcelable Book;
这时候重新编译程序,工程就会自动生成 BookManager.aidl 接口对应的文件。
app\build\generated\source\aidl\debug\com\wshunli\ipc\demoIBookManager.java
2、创建服务端
服务端使用 IBookManager.Stub() 方法创建 Binder 实例并在 onBind() 方法中返回。
public class BookManagerService extends Service { private static final String TAG = "BookManagerService" ; private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList <>(); 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); } @Override public void basicTypes (int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } }; public BookManagerService () { } @Override public void onCreate () { super .onCreate(); mBookList.add(new Book ("android" )); mBookList.add(new Book ("ios" )); } @Override public IBinder onBind (Intent intent) { return mBinder; } }
其中 onCreate() 方法中填充了数据。
当然在 AndroidManife 文件中要配置 Service
<service android:name ="com.wshunli.ipc.demo.BookManagerService" android:enabled ="true" android:exported ="true" android:process =":remote" />
3、客户端
客户端还是使用 bindService() 方法绑定服务。
public class BookManagerActivity extends AppCompatActivity { private static final String TAG = "BookManagerActivity" ; private ServiceConnection connection = new ServiceConnection () { @Override public void onServiceConnected (ComponentName name, IBinder service) { IBookManager bookManager = IBookManager.Stub.asInterface(service); try { List<Book> bookList = bookManager.getBookList(); Log.d(TAG, "onServiceConnected: " + bookList.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_book_manager); Intent intent = new Intent (BookManagerActivity.this , BookManagerService.class); bindService(intent, connection, BIND_AUTO_CREATE); } @Override protected void onDestroy () { unbindService(connection); super .onDestroy(); } }
其中 IBookManager 对象来调用具体服务器方法,获取数据。
AIDL 的功能远不止这些,后面再深入研究。
参考资料 1、《Android开发艺术探索》 – 2.4.4 使用 AIDL 2、Android 接口定义语言 (AIDL) | Android Developershttps://developer.android.com/guide/components/aidl 3、Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用 | 刘望舒的博客http://liuwangshu.cn/application/ipc/3-aidl.html