AIDL基本使用(二)
来源:互联网 发布:淘宝海外集运 编辑:程序博客网 时间:2024/06/08 16:37
AIDL基本使用(二)
将观察者模式和AIDL结合起来使用,使用RemoteCallBackList管理跨进程的接口。普通接口由于使用Binder传输需要序列化和反序列化,每次客户端传递过来的都是一个新对象,无法做到解注册。而RemoteCallBackList内部使用ArrayMap,将接口和Binder对象匹配起来。
注:阅读本文章前请先阅读前一篇文章AIDL基本使用(一)
这里的观察者模式指的是客户端在服务端注册,服务端事件发生时通知客户端执行相应的事件。也就是客户端需要在服务端进行注册和解注册。本文紧接上篇文章,以图书馆(服务端)图书到来,通知客户端图书到来为例
操作步骤
1.跨进程的接口使用AIDL,所以先写一个aidl接口。
package com.example.xin.aidldemo;import com.example.xin.aidldemo.Book;interface IOnNewBookArrivedListener { void onNewBookArrived(in Book book);}
2.在IBookManager接口中新增注册和解注册两个方法。
package com.example.xin.aidldemo;import com.example.xin.aidldemo.Book;import com.example.xin.aidldemo.IOnNewBookArrivedListener;interface IBookManager { List<Book> getBookList(); void addBook(in Book book); void registerListener(in IOnNewBookArrivedListener listener); void unRegisterListener(IOnNewBookArrivedListener listener);}
3.服务端实现注册和解注册,其实就是用一个RemoteCallBackList来存放注册进来的接口,当图书到达图书馆时,逐一调用这些接口的实现。图书到达图书馆这一行为用一个线程循环执行模拟。
public class BookManagerService extends Service { private CopyOnWriteArrayList<Book> mBookList; private RemoteCallbackList<IOnNewBookArrivedListener> mNewBookArrivedListenerList; private boolean isDestroy = false; private Binder mBinder = new IBookManager.Stub() { @Override public List<Book> getBookList() throws RemoteException { Log.d("ZXX","getBookList Service"); return mBookList; } @Override public void addBook(Book book) throws RemoteException { mBookList.add(book); } @Override public void registerListener(IOnNewBookArrivedListener listener) throws RemoteException { //注册接口,将接口添加到RemoteCallBackList mNewBookArrivedListenerList.register(listener); } @Override public void unRegisterListener(IOnNewBookArrivedListener listener) throws RemoteException { //解注册接口 mNewBookArrivedListenerList.unregister(listener); } }; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onCreate() { mBookList = new CopyOnWriteArrayList<>(); mBookList.add(new Book(1,"测试")); mBookList.add(new Book(2,"测试2")); mNewBookArrivedListenerList = new RemoteCallbackList<>(); new Thread(new ServiceWorker()).start(); } //图书到达图书馆就逐一通知客户端执行 private void newBookArrived(Book book){ mNewBookArrivedListenerList.beginBroadcast(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { for(int i = 0; i < mNewBookArrivedListenerList.getRegisteredCallbackCount(); i++){ IOnNewBookArrivedListener listener = mNewBookArrivedListenerList.getBroadcastItem(i); if(listener != null){ try { listener.onNewBookArrived(book); } catch (RemoteException e) { e.printStackTrace(); } } } } mNewBookArrivedListenerList.finishBroadcast(); } @Override public void onDestroy() { super.onDestroy(); isDestroy = true; } //模拟图书到达图书馆 private class ServiceWorker implements Runnable{ @Override public void run() { while(!isDestroy){ try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } int bookId = mBookList.size() + 1; Log.e("ZXX","size: " + mBookList.size()); Book book = new Book(bookId, "测试"+bookId); mBookList.add(book); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { newBookArrived(book); } } } }}
4.客户端注册接口
public class MainActivity extends AppCompatActivity { private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { IBookManager bookManager = IBookManager.Stub.asInterface(iBinder); try { List<Book> list = bookManager.getBookList(); for(Book b : list){ Log.d("ZXX",b.getName()); } //注册监听到服务端 bookManager.registerListener(mNewBookListener); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, BookManagerService.class); bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE); } //注意是AIDL接口,new的时候是new 一个Stub接口 private IOnNewBookArrivedListener mNewBookListener = new IOnNewBookArrivedListener.Stub() { @Override public void onNewBookArrived(Book book) throws RemoteException { Log.e("ZXX",book.getName()); } };}
打出的Log:
08-09 23:24:20.722 23188-23188/com.example.xin.aidldemo D/ZXX: 测试
08-09 23:24:20.722 23188-23188/com.example.xin.aidldemo D/ZXX: 测试2
08-09 23:24:25.613 23188-23203/com.example.xin.aidldemo E/ZXX: 测试3
08-09 23:24:30.615 23188-23205/com.example.xin.aidldemo E/ZXX: 测试4
08-09 23:24:35.617 23188-23207/com.example.xin.aidldemo E/ZXX: 测试5
08-09 23:24:40.620 23188-23207/com.example.xin.aidldemo E/ZXX: 测试6
- AIDL基本使用(二)
- AIDL使用详解 (二)AndroidStudio中 创建 AIDL service
- AIDL的基本使用(一)
- AIDL的基本使用
- AIDL的基本使用
- Binder 框架(二)aidl的使用
- Android中AIDL的使用(二)
- AIDL使用(二)
- 安卓IPC之aidl使用(二)---aidl本地实现
- AIDL使用学习(二):跨进程回调以及RemoteCallbackList
- AIDL使用教程二(传递非默认类型数据)
- AIDL基本使用1----调用服务端方法
- AIDL基本使用2— 传递对象
- Andorid中的AIDL(二)
- Android 深入浅出AIDL(二)
- Android AIDL学习(二)
- Emacs基本使用(二)
- Fragment基本使用(二)
- Ubuntu安装Nginx+MySQL+PHP(LNMP)
- 使用自己训练的KITTI数据集,用Python做detectnet侦测
- 微信开发,小程序支付之间的关联-小程序支付开发2
- 重复的轮子通用操作系统内核
- 中国剩余定理
- AIDL基本使用(二)
- Nvidia SDK11 之 PNPatches(细化算法技术学习)
- sublimeText3使用的一些基础配置
- 启动tomcat出现out of memory错误
- 100道C#面试题(.net开发人员必备)
- bzoj 3376: [Usaco2004 Open]Cube Stacking 方块游戏 带权并查集
- Codeforces 705D Ant Man DP(贡献)
- 扫描手机sdka里的音乐并播放
- 经典.net面试题目