RemoteCallbackList 机制分析
来源:互联网 发布:linux thrift源码安装 编辑:程序博客网 时间:2024/06/03 22:45
前言:
RemoteCallbackList主要用于aidl的跨进程通信,并且主要是服务端回调客户端的方法。
回调的aidl文件如下,
package com.•••;interface ICallback { void onGetservice(String info);}
主要分为2步,
private final RemoteCallbackList<ICallback> mRemoteCallbacks = new RemoteCallbackList<ICallback>();private ICallback mCallback;
1,客户端调用服务端方法时进行回调注册,
@Overridepublic void queryFwVersion(ICallback callback) throws RemoteException { if (callback != null) { mCallback = callback; mRemoteCallbacks.register(callback); ••• }}
2,服务端的回调,
final int N = mRemoteCallbacks.beginBroadcast(); for (int i = 0; i < N; i++) {//遍历逐个回调 try { mRemoteCallbacks.getBroadcastItem(i). onGetservice (sa); } catch (RemoteException e) { e.printStackTrace(); } }mRemoteCallbacks.finishBroadcast();mRemoteCallbacks.unregister(mCallback);
最后一般在onDestroy方法中会调用,
mRemoteCallbacks. kill()
这里一共涉及到6个方法,下面逐个分析。
1, register
RemoteCallbackList注册回调方法如下,
public boolean register(E callback) { return register(callback, null);}
register方法如下,
public boolean register(E callback, Object cookie) { synchronized (mCallbacks) { if (mKilled) { return false; } IBinder binder = callback.asBinder(); try { Callback cb = new Callback(callback, cookie); binder.linkToDeath(cb, 0);//监听客户端是否进程是否终止 mCallbacks.put(binder, cb); return true; } catch (RemoteException e) { return false; } } }
主要是将callback和对应的Ibinder对象放入mCallbacks哈希表中,定义如下,
ArrayMap<IBinder, Callback> mCallbacks = new ArrayMap<IBinder, Callback>();
Ibinder对象主要是监听客户端是否终止。
Callback是RemoteCallbackList的内部类,主要是实现了binderDied方法, Callback定义如下,
private final class Callback implements IBinder.DeathRecipient { final E mCallback; final Object mCookie; Callback(E callback, Object cookie) { mCallback = callback; mCookie = cookie; } public void binderDied() { synchronized (mCallbacks) { mCallbacks.remove(mCallback.asBinder()); } onCallbackDied(mCallback, mCookie); }}
如果远程客户端进程终止,则会回调binderDied方法, binderDied方法首先从mCallbacks中删除客户端的回调对象,
然后调用onCallbackDied方法, onCallbackDied其实是个空方法, RemoteCallbackList并未实现,当然服务端可以
覆盖实现,也可以不实现。
2 unregister
unregister方法和register方法刚好相反,
public boolean unregister(E callback) { synchronized (mCallbacks) { Callback cb = mCallbacks.remove(callback.asBinder()); if (cb != null) { cb.mCallback.asBinder().unlinkToDeath(cb, 0); return true; } return false; } }
unregister首先从mCallbacks中移除对应的Callback对策,然后解除客户端的监听,
3, beginBroadcast
beginBroadcast方法如下,
public int beginBroadcast() { synchronized (mCallbacks) { if (mBroadcastCount > 0) { throw new IllegalStateException( "beginBroadcast() called while already in a broadcast"); } final int N = mBroadcastCount = mCallbacks.size(); if (N <= 0) { return 0; } Object[] active = mActiveBroadcast; if (active == null || active.length < N) { mActiveBroadcast = active = new Object[N]; } for (int i=0; i<N; i++) { active[i] = mCallbacks.valueAt(i); } return N; } }
将mCallbacks 中元素的个数保存在mBroadcastCount变量中,
将mCallbacks 中元素逐个保存在mActiveBroadcast组中,当然通常mCallbacks仅有一个元素。
4, getBroadcastItem
public E getBroadcastItem(int index) { return ((Callback)mActiveBroadcast[index]).mCallback; }
getBroadcastItem根据下标获取mActiveBroadcast中的mCallback对象。
通常紧接着就调用其aidl方法。
5, finishBroadcast
public void finishBroadcast() { if (mBroadcastCount < 0) { throw new IllegalStateException( "finishBroadcast() called outside of a broadcast"); } Object[] active = mActiveBroadcast; if (active != null) { final int N = mBroadcastCount; for (int i=0; i<N; i++) { active[i] = null; } } mBroadcastCount = -1; }
finishBroadcast方法将active中的元素置为空,然后将变量赋为-1.
6, kill
public void kill() { synchronized (mCallbacks) { for (int cbi=mCallbacks.size()-1; cbi>=0; cbi--) { Callback cb = mCallbacks.valueAt(cbi); cb.mCallback.asBinder().unlinkToDeath(cb, 0); } mCallbacks.clear(); mKilled = true; } }
将mCallbacks清空,并且将mKilled变量赋值为true。
其实, RemoteCallbackList类还是很简单的,
ArrayMap<IBinder, Callback> mCallbacks = new ArrayMap<IBinder, Callback>();
mCallbacks变量主要保存客户端注册的Callback对象,并监听客户端进程的状态。
private Object[] mActiveBroadcast;
mActiveBroadcast保存mCallbacks中的元素,利于逐个变量。
private int mBroadcastCount = -1;private boolean mKilled = false;mBroadcastCount保存mCallbacks中元素的个数,mKilled表示是否kill。
- RemoteCallbackList 机制分析
- aidl 中通过RemoteCallbackList 运用到的回调机制: service回调activity的方法
- aidl 中通过RemoteCallbackList 运用到的回调机制: service回调activity的方法 .
- aidl 中通过RemoteCallbackList 运用到的回调机制: service回调activity的方法
- aidl 中通过RemoteCallbackList 运用到的回调机制: service回调activity的方法
- aidl 中通过RemoteCallbackList 运用到的回调机制: service回调activity的方法
- aidl ( 七) RemoteCallbackList
- Android RemoteCallbackList类
- RemoteCallbackList的使用
- Android RemoteCallbackList类
- java异常机制分析
- EasyLon加密机制分析
- Java回收机制分析
- ECOS中断机制分析
- 深入分析异常机制!
- 深入分析异常机制!
- OpenLayers事件机制分析
- Netfilter实现机制分析
- Linux crontab定时任务配置方法(详解)
- flowable EngineConfiguration的实现分析(2)
- 奶爸英语学习课程要点(第7课)
- 机器学习集训营---第三周总结
- SIT和UAT的区别
- RemoteCallbackList 机制分析
- A Knight's Journey
- 八、Java中的数据类型
- 基础篇一---一个服务的访问过程
- 食物链(poj--1182)
- Java中的方法以及方法重载
- 深度学习笔记---梯度消失、梯度激增
- Python勇冠排行榜首,名企大咖教你免费学
- web测试和app测试重点