AIDL 全稱:android interface defination language 安卓接口定義語言。適用於進程間通信。
首先創建Book對象
package com.example.test.aidl;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
/**
* Description:
*/
public class Book implements Parcelable{
private int bookId;
private String bookName;
public Book(int bookId,String bookName){
this.bookId = bookId;
this.bookName = bookName;
}
protected Book(Parcel in) {
bookId = in.readInt();
bookName = in.readString();
}
public static final Creator<Book> CREATOR = new Creator<Book>() {
@Override
public Book createFromParcel(Parcel in) {
return new Book(in);
}
@Override
public Book[] newArray(int size) {
return new Book[size];
}
};
public int getBookId() {
return bookId ;
}
public void setBookId(int bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName ;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(bookId);
dest.writeString(bookName);
}
}
創建Book.aidl文件
修改Book.aidl內容
package com.example.test.aidl;
parcelable Book;
再創建IBookManager.aidl文件
提供兩個方法,addBook和getBookList方法
package com.example.test.aidl;
import com.example.test.aidl.Book;
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
}
接下來就服務端,創建BookManagerService繼承Service,在onCreate()中初始化添加了4本書。並創建一個Binder對象在onBind()中返回。
package com.example.test.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Description:
*/
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 onCreate() {
super.onCreate();
mBookList.add(new Book(1,"西遊記"));
mBookList.add(new Book(2,"紅樓夢"));
mBookList.add(new Book(3,"水滸傳"));
mBookList.add(new Book(4,"三國演義"));
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
在AndroidManifest.xml中註冊
<service
android:name=".aidl.BookManagerService"
android:process=":BookManagerService">
</service>
創建AidlActivity,和BookManagerService建立連接。
package com.example.test.aidl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.example.test.R;
import java.util.List;
public class AidlActivity extends AppCompatActivity {
private static final String TAG = "AidlActivity";
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IBookManager iBookManager = IBookManager.Stub.asInterface(service);
try {
List<Book> bookList = iBookManager.getBookList();
for (int i = 0; i < bookList.size(); i++) {
Book book = bookList.get(i);
Log.e(TAG, "Book: bookName ————"+book.getBookName() +"||| bookId ————" +book.getBookId());
}
} catch (RemoteException e) {
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aidl);
Intent intent = new Intent(this,BookManagerService.class);
bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
unbindService(mServiceConnection);
super.onDestroy();
}
}
運行程序,查看控制檯數據。
在這裏只調用了getBookList()方法,嘗試調用一下addBook()方法。修改如下:
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IBookManager iBookManager = IBookManager.Stub.asInterface(service);
try {
//添加一本書籍
iBookManager.addBook(new Book(5,"三打白骨精"));
List<Book> bookList = iBookManager.getBookList();
for (int i = 0; i < bookList.size(); i++) {
Book book = bookList.get(i);
Log.e(TAG, "Book: bookName ————"+book.getBookName() +"||| bookId ————" +book.getBookId());
}
} catch (RemoteException e) {
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
重新運行,發現數據已經添加上去了。
下面我們來模擬一下每當有新的圖書添加進來就通知用戶。首先需要提供一個AIDL接口,用戶可以開啓提醒和取消提醒。
首先創建IOnNewBookArrivedListener.aidl文件,並提供onNewBookArrived()方法
// IOnNewBookArrivedListener.aidl
package com.example.test.aidl;
import com.example.test.aidl.Book;
// Declare any non-default types here with import statements
interface IOnNewBookArrivedListener {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void onNewBookArrived(in Book book);
}
然後在原有的IBookManager.aidl中添加兩個新方法
package com.example.test.aidl;
import com.example.test.aidl.Book;
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
void registerListener(IOnNewBookArrivedListener listener);
void unregisterListener(IOnNewBookArrivedListener listener);
}
BookManagerService中也需要修改下,並在OnCreate()中啓動了一個線程,每隔5秒添加一本新書到BookList中。
package com.example.test.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Description:
*/
public class BookManagerService extends Service{
private static final String TAG = "BookManagerService";
private AtomicBoolean mAtomicBoolean = new AtomicBoolean(false);
private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
private CopyOnWriteArrayList<IOnNewBookArrivedListener> mListenerList = 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 registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
if (!mListenerList.contains(listener)) {
mListenerList.add(listener);
}
Log.e(TAG, "registerListener: mListenerList大小"+mListenerList.size());
}
@Override
public void unregisterListener(IOnNewBookArrivedListener listener) throws RemoteException {
if (mListenerList.contains(listener)) {
mListenerList.remove(listener);
}
Log.e(TAG, "registerListener: mListenerList大小"+mListenerList.size());
}
};
@Override
public void onCreate() {
super.onCreate();
mBookList.add(new Book(1,"西遊記"));
mBookList.add(new Book(2,"紅樓夢"));
mBookList.add(new Book(3,"水滸傳"));
mBookList.add(new Book(4,"三國演義"));
new Thread(new ServiceWorker()).start();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private void onNewBookArrived(Book book) throws RemoteException {
mBookList.add(book);
for (int i = 0; i < mListenerList.size(); i++) {
IOnNewBookArrivedListener iOnNewBookArrivedListener = mListenerList.get(i);
iOnNewBookArrivedListener.onNewBookArrived(book);
}
}
private class ServiceWorker implements Runnable{
@Override
public void run() {
//爲真時一直執行
while (!mAtomicBoolean.get()){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int bookId = mBookList.size()+1;
Book book = new Book(bookId,"火影忍者第"+bookId+"話");
try {
onNewBookArrived(book);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onDestroy() {
mAtomicBoolean.set(true);
super.onDestroy();
}
}
然後AidlActivity中在連接BookManagerService時開啓提醒,即註冊,銷燬的時候取消提醒,即取消註冊。
package com.example.test.aidl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.example.test.R;
import com.example.test.utils.Constants;
import java.util.List;
public class AidlActivity extends AppCompatActivity {
private static final String TAG = "AidlActivity";
private IBookManager mIBookManager;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IBookManager iBookManager = IBookManager.Stub.asInterface(service);
try {
mIBookManager = iBookManager;
iBookManager.addBook(new Book(5,"三打白骨精"));
List<Book> bookList = iBookManager.getBookList();
for (int i = 0; i < bookList.size(); i++) {
Book book = bookList.get(i);
Log.e(TAG, "Book: bookName ————"+book.getBookName() +"||| bookId ————" +book.getBookId());
}
//註冊
iBookManager.registerListener(mIOnNewBookArrivedListener);
} catch (RemoteException e) {
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case Constants.BOOKARRIVED:
Book book = (Book) msg.obj;
Log.e(TAG, "Book: bookName ————"+book.getBookName() +"||| bookId ————" +book.getBookId());
break;
default:
super.handleMessage(msg);
break;
}
}
};
private IOnNewBookArrivedListener mIOnNewBookArrivedListener = new IOnNewBookArrivedListener.Stub() {
@Override
public void onNewBookArrived(Book book) throws RemoteException {
mHandler.obtainMessage(Constants.BOOKARRIVED,book).sendToTarget();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aidl);
Intent intent = new Intent(this,BookManagerService.class);
bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
if (mIBookManager != null && mIBookManager.asBinder().isBinderAlive()) {
try {
//取消註冊
mIBookManager.unregisterListener(mIOnNewBookArrivedListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
unbindService(mServiceConnection);
super.onDestroy();
}
}
然後重新運行程序。可以看出來每隔5秒就會收到新書的消息。