一、前言
都说不懂Binder,就不懂Android。好吧,写个实例,不废话,只上干货。
二、步骤
1.写一个Binder代理的接口类,实现方法代理。以便通信调用。(对于小白来说,这里是关键,不知道怎么写)
public interface IMyBookInterface extends android.os.IInterface {
ArrayListgetBooks()throws android.os.RemoteException;
void addBook(Book book)throws android.os.RemoteException;
public static abstract class Stub extends android.os.Binder implements IMyBookInterface {
private static final java.lang.String DESCRIPTOR ="com.usc.demo.aidl.IMyBookInterface";
public Stub() {
this.attachInterface(this,DESCRIPTOR);
}
public static IMyBookInterface asInterface(android.os.IBinder obj) {
if ((obj ==null)) {
return null;
}
android.os.IInterface iin =obj.queryLocalInterface(DESCRIPTOR);
if (((iininstanceof IMyBookInterface))) {
return ((IMyBookInterface) iin);
}
return new IMyBookInterface.Stub.Proxy(obj);
}
@Override
? ? ? ? public android.os.IBinder asBinder() {
return this;
}
@Override
? ? ? ? public boolean onTransact(int code,android.os.Parcel data,android.os.Parcel reply,int flags)throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_addBook: {
data.enforceInterface(DESCRIPTOR);
Book book = (Book)data.readValue(Book.class.getClassLoader());
this.addBook(book);
reply.writeNoException();
return true;
}
case TRANSACTION_getBooks: {
data.enforceInterface(DESCRIPTOR);
this.getBooks();
reply.writeNoException();
return true;
}
}
return super.onTransact(code,data,reply,flags);
}
private static class Proxy implements IMyBookInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote =remote;
}
@Override
? ? ? ? ? ? public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
? ? ? ? ? ? public ArrayListgetBooks()throws RemoteException {
Parcel _data =Parcel.obtain();
Parcel _reply =Parcel.obtain();
ArrayList _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getBooks, _data, _reply,0);
_reply.readException();
_result = _reply.readArrayList(Book.class.getClassLoader());
}finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
? ? ? ? ? ? public void addBook(Book book)throws RemoteException {
android.os.Parcel _data =android.os.Parcel.obtain();
android.os.Parcel _reply =android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeValue(book);
mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply,0);
_reply.readException();
}finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_getBooks = (android.os.IBinder.FIRST_CALL_TRANSACTION);
static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION +1);
}
}
2.写一个服务Service,新建一个上述接口的实例,这里是Service和后面Activity通信的通道。
public class BookManagerService extends Service {
private static final String TAG ="BMS";
private ArrayListmBookList =new ArrayList();
private Binder mBinder =new IMyBookInterface.Stub() {
@Override
? ? ? ? public ArrayListgetBooks()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,"Android"));
mBookList.add(new Book(2,"Ios"));
}
@Override
? ? public IBinder onBind(Intent intent) {
return mBinder;
}
}
3.最后写一个Activity,使用ServiceConnection建立连接,获取它管理的Binder,继而传递数据。
public class BookActivity extends Activity {
private TextView mTextView;
private IMyBookInterface.Stub mBinder;
@Override
? ? protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
mTextView =findViewById(R.id.book);
// 绑定服务
? ? ? ? Intent intent =new Intent(this,BookManagerService.class);
bindService(intent,serviceConnection,Context.BIND_AUTO_CREATE);
doEvent();
}
private final ServiceConnection serviceConnection =new ServiceConnection() {
@Override
? ? ? ? public void onServiceConnected(ComponentName name,IBinder service) {
// 获取Binder对象
? ? ? ? ? ? mBinder = (IMyBookInterface.Stub)service;
// 可以调用服务中的方法
? ? ? ? ? ? showBooks();
}
@Override
? ? ? ? public void onServiceDisconnected(ComponentName name) {
mBinder =null;
}
};
private void doEvent() {
new Thread(new Runnable() {
@Override
? ? ? ? ? ? public void run() {
try {
Thread.sleep(5000);
}catch (InterruptedException e) {
throw new RuntimeException(e);
}
Book book =new Book(101,"Binder实例");
try {
mBinder.addBook(book);
}catch (RemoteException e) {
Log.e("BookActivity","run: addBook error");
}
showBooks();
}
}).start();
}
private void showBooks() {
try {
List books =mBinder.getBooks();
Log.i("BookActivity","showBooks: books = " + books.toString());
runOnUiThread(() -> {
mTextView.setText(books.toString());
});
}catch (RemoteException e) {
Log.e("BookActivity","showBooks: ");
}
}
@Override
? ? protected void onDestroy() {
super.onDestroy();
// 解绑服务
? ? ? ? if (mBinder !=null) {
unbindService(serviceConnection);
}
}
}
三、结尾
实体类和UI,小伙伴就自己写,这里放一个结果吧
1.activity获取service图书
2.activity向service增加一本图书,再展示。