先看一下文件目录:
service端:
然后是客户端:
service端代码:
AIDL文件:
IOnNewBookArrivedListener
// IOnNewBookArrivedListener.aidl
package com.sjq.service;
// Declare any non-default types here with import statements
import com.sjq.service.Book;
interface IOnNewBookArrivedListener {
void onNewBookArrived(in Book newbook);
}
interface IBookManager:
// IBookManager.aidl
package com.sjq.service;
// Declare any non-default types here with import statements
import com.sjq.service.Book;
import com.sjq.service.IOnNewBookArrivedListener;
interface IBookManager {
void addBook(in Book book);
List<Book> getBookList();
void registerOnNewBookArrivedListener(in IOnNewBookArrivedListener listener);
void unregisterOnNewBookArrivedListener(in IOnNewBookArrivedListener listener);
}
Book:
// Book.aidl
package com.sjq.service;
// Declare any non-default types here with import statements
parcelable Book;
Service代码:
package com.sjq.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
public class MyService extends Service {
//书本集合
CopyOnWriteArrayList<Book> list;
//所有注册过的监听的客户端
RemoteCallbackList<IOnNewBookArrivedListener> listeners;
private AtomicBoolean isServiceDestoryed = new AtomicBoolean(false);
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
list = new CopyOnWriteArrayList<>();
list.add(new Book(0, "深入理解Java虚拟机" + 0));
list.add(new Book(list.size() + 1, "深入理解Java虚拟机" + list.size() + 1));
listeners = new RemoteCallbackList<>();
new Thread(new AddBookRunnable()).start();
return binder;
}
IBookManager.Stub binder = new IBookManager.Stub() {
@Override
public void addBook(Book book) throws RemoteException {
list.add(book);
// Log.i("Book", "addBook:---------->" + book.toString());
}
@Override
public List<Book> getBookList() throws RemoteException {
// Log.i("Book", "getBookList:---------->" + list.toString());
return list;
}
@Override
public void registerOnNewBookArrivedListener(IOnNewBookArrivedListener listener) throws RemoteException {
listeners.register(listener);
}
@Override
public void unregisterOnNewBookArrivedListener(IOnNewBookArrivedListener listener) throws RemoteException {
listeners.unregister(listener);
}
};
class AddBookRunnable implements Runnable {
@Override
public void run() {
while (!isServiceDestoryed.get()) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int bookId = list.size() + 1;
Book book = new Book(bookId, "深入理解Java虚拟机");
AddBook(book);
}
}
}
//在service线程中增加新书
private void AddBook(Book book) {
list.add(book);
final int n = listeners.beginBroadcast();
for (int i = 0; i < n; i++) {
IOnNewBookArrivedListener lis = listeners.getBroadcastItem(i);
try {
if(lis!=null){
//和普通的回调是一样的,不过此处的回调实现是在客户端实现的
//通知所有注册过的客户端,有新书
lis.onNewBookArrived(book);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
listeners.finishBroadcast();
}
}
Book:
package com.sjq.service;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by cs001 on 2016/6/29.
*/
public class Book implements Parcelable{
int BookId;
String BookName;
public Book(int bookId, String bookName) {
this.BookId = bookId;
this.BookName = bookName;
}
protected Book(Parcel in) {
this.BookId = in.readInt();
this.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];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(BookId);
parcel.writeString(BookName);
}
@Override
public String toString() {
return "Book{" +
"BookId=" + BookId +
", BookName='" + BookName + '\'' +
'}';
}
}
然后是客户端,复制过来的AIDL文件和实体类文件目录结构还是要和service完全一致:
package com.sjq.aidl_client;
import android.content.ComponentName;
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 android.view.View;
import android.widget.Button;
import com.sjq.service.Book;
import com.sjq.service.IBookManager;
import com.sjq.service.IOnNewBookArrivedListener;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
Button btn;
ArrayList<Book> books;
private IBookManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.sjq.service", "com.sjq.service.MyService"));
bindService(intent, conn, BIND_AUTO_CREATE);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
books = (ArrayList<Book>) manager.getBookList();
Log.i("Book", books.toString());
manager.addBook(new Book(books.size() + 1, "Java虚拟机" + books.size() + 1));
books = (ArrayList<Book>) manager.getBookList();
Log.i("Book", books.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
//连接成功回调
ServiceConnection conn = new ServiceConnection() {
//运行在UI线程
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i("Book", "------onServiceConnected-------");
//连接成功,将Binder对象转换为IBookManager接口对象,同一个进程返回IBookManager.Stub
//不同进程返回IBookManager.Stub.Proxy
manager = IBookManager.Stub.asInterface(iBinder);
try {
//注册监听器
manager.registerOnNewBookArrivedListener(listener);
Log.i("listener", "manager.registerOnNewBookArrivedListener(listener)");
} catch (RemoteException e) {
e.printStackTrace();
}
}
//运行在UI线程
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
//有新书监听 实现AIDL接口的子类
IOnNewBookArrivedListener.Stub listener = new IOnNewBookArrivedListener.Stub() {
@Override
public void onNewBookArrived(Book newbook) throws RemoteException {
Log.i("Book", "onNewBookArrived:--------> " + "来新书了!!!!");
}
};
@Override
protected void onDestroy() {
super.onDestroy();
if (listener != null && manager.asBinder().isBinderAlive()) {
try {
manager.unregisterOnNewBookArrivedListener(listener);
Log.i("listener", "manager.unregisterOnNewBookArrivedListener(listener)");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
个人理解: