本文将带你了解Android应用开发android开发AIDL跨进程通信:AIDL中RemoteCallbackList的使用及权限验证方式详解,希望本文对大家学Android有所帮助。
业务场景:
现在要实现每新增一个员工,就通知相应的部门人员
1、提供一个AIDL接口,由于AIDL中无法使用普通接口,所以提供一个AIDL接口
// IOnNewPersonArrivedListener.aidl
package com.wuc.aidltest;
// Declare any non-default types here with import statements
import com.wuc.aidltest.Person;
// 当服务端有新人加入时,就通知每一个已经申请提醒功能的用户,由于AIDL中无法使用普通接口,所以提供一个AIDL接口
interface IOnNewPersonArrivedListener {
void onNewPersonArrived(in Person person);
}
2、 修改ICalculateInterface代码,新增注册与注销监听器代码
// ICalculateInterface.aidl
package com.wuc.aidltest;
// Declare any non-default types here with import statements
import com.wuc.aidltest.Person;
import com.wuc.aidltest.IOnNewPersonArrivedListener;
interface ICalculateInterface {
//计算两个数的和
int addNum(int num1,int num2);
//除了基本数据类型,其他类型的参数都需要标上方向类型:in(输入), out(输出), inout(输入输出)
List addPerson(in Person person);
void registerListener(IOnNewPersonArrivedListener listener);
void unregisterListener(IOnNewPersonArrivedListener listener);
}
IRemoteService代码
package com.wuc.aidltest;
public class IRemoteService extends Service {
private static final String TAG = "IRemoteService";
//存储注册监听客户端集合
private final CopyOnWriteArrayList mListenerList = new CopyOnWriteArrayList <>();
/**
* CopyOnWriteArrayList支持并发读写,AIDL方法是在服务端的Binder线程池中执行的,因此当多个客户端同时连接的时候,
* 会存在多个线程同时访问的情形,所以我们要在AIDL方法中处理线程同步,这里使用CopyOnWriteArrayList来进行自动的线程同步
*
* 因为AIDL中所支持的是抽象的List,二List只是一个接口,因此虽然服务端返回的是CopyOnWriteArrayList,但是在Binder中
* 会按照List的规范去访问数据并最终形成一个新的ArrayList传递给客户端,所以采用CopyOnWriteArrayList是可以的,类似的
* 还有ConcurrentHashMap
*/
private CopyOnWriteArrayList mPersonList;
private AtomicBoolean mIsServiceDestoryed = new AtomicBoolean(false);
private IBinder mIBinder = new ICalculateInterface.Stub() {
@Override
public int addNum(int num1, int num2) throws RemoteException {
return num1 + num2;
}
@Override
public List addPerson(Person person) throws RemoteException {
mPersonList.add(person);
return mPersonList;
}
@SuppressLint("NewApi")
@Override
public void registerListener(IOnNewPersonArrivedListener listener) throws RemoteException {
if (!mListenerList.contains(listener)) {
mListenerList.add(listener);//添加监听
} else {
Log.d(TAG, "already exists.");
}
Log.d(TAG, "registerListener,size:" + mListenerList.size());
}
@SuppressLint("NewApi")
@Override
public void unregisterListener(IOnNewPersonArrivedListener listener) throws RemoteException {
if (mListenerList.contains(listener)) {
mListenerList.remove(listener);//移除监听
Log.d(TAG, "unregister listener succeed.");
} else {
Log.d(TAG, "not found,can not unregister.");
}
Log.d(TAG, "unregisterListener,current size:" + mListenerList.size());
}
};
@Override
public void onCreate() {
super.onCreate();
new Thread(new ServiceWorker()).start();
}
@Override
public void onDestroy() {
mIsServiceDestoryed.set(true);
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
mPersonList = new CopyOnWriteArrayList<>();
return mIBinder;
}
private void onNewPersonArrived(Person person) throws RemoteException {
mPersonList.add(person);
Log.d(TAG, "onNewPersonArrived, notify listener:" + mListenerList.size());
for (int i = 0; i
IOnNewPersonArrivedListener listener = mListenerList.get(i);
Log.d(TAG, "onNewPersonArrived, notify listener:" + listener);
listener.onNewPersonArrived(person);
}
}
/**
* 每个5秒增加一个新人,并通知所有感兴趣的员工
*/
private class ServiceWorker implements Runnable {
@Override
public void run() {
while (!mIsServiceDestoryed.get()) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Person person = new Person("new person name:" + 2, 22);
try {
onNewPersonArrived(person);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
}
MainActivity代码
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!