AIDL基本使用(二)

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值