2.4 AIDL

作者: 努力生活的西鱼 | 来源:发表于2021-06-27 18:04 被阅读0次
AIDL

跨进程通信,使用AIDL来实现的基本步骤,以及需要注意的点。

  1. 创建AIDL中使用到的类,继承Parcelable
  2. 右键,创建AIDL文件夹,这个文件夹是和java文件夹同级的。
  3. 创建一个类的AIDL文件,内容为parcelable Book;这样。
  4. 在上面创建的那个AIDL文件中,引入类,并写入客户端可能使用的方法。
import com.wm.aidlservice.Book;
import com.wm.aidlservice.IOnNewBookArrivedListener;

interface IBookManager {

    void addBook(in Book book);

    List<Book> getBookList();

    void registerListener(IOnNewBookArrivedListener listener);

    void unregisterListener(IOnNewBookArrivedListener listener);

}
  1. 创建一个Service,重写AIDL里面的Stub类,然后将Binder返回。

  2. 注意Service,在manifest添加category

<service
    android:name=".BookManagerService"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.wm.aidlservice.BookManagerService"/>
    </intent-filter>
</service>
  1. 在客户端程序里面,绑定此Service
Intent intent = new Intent();
intent.setAction("com.wm.aidlservice.BookManagerService");
intent.setPackage("com.wm.aidlservice");
bindService(intent, serviceConnection, BIND_AUTO_CREATE);

接下来就可以,调用服务端的方法了。

需要注意的是
  1. 服务端的方法,是运行在Binder线程中的,客户端防止发生ANR的情况。

  2. 当服务端,通过观察者模式去调用客户端方法的时候,此时客户端的方法运行在Binder中,防止服务端出现ANR

  3. 基于2,注册和解注册的时候,需要使用RemoteCallbackList

private RemoteCallbackList<IOnNewBookArrivedListener> listeners = new RemoteCallbackList<>();

// 注册
listeners.register(listener);

// 解注册
listeners.unregister(listener);

// 采用这种方式调用
final int N = listeners.beginBroadcast();
for (int i = 0; i < N; i++) {
    IOnNewBookArrivedListener listener = listeners.getBroadcastItem(i);
    if (listener != null) {
        listener.onNewBookArrived(book);
    }
}
listeners.finishBroadcast();
  1. AIDL的服务端,设置权限验证的问题,1是在onBinder()中设置(两个APP,无效),2是通过onTransact()中设置,类似过滤器,可以筛选包名或者权限。
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    String packageName = null;
    String[] packages = getPackageManager().getPackagesForUid(getCallingUid());
    if (packages != null && packages.length > 0) {
        packageName = packages[0];
    }

    if (packageName == null) {
        return false;
    }

    boolean result = checkPermission(BookManagerService.this,"com.wm.aidlservice.permission.ACCESS_BOOK_SERVICE",packageName);
    if (!result) {
        Log.d(TAG,"授权失败");
        return false;
    }

    return super.onTransact(code, data, reply, flags);
}

private boolean checkPermission(Context mContext,String permissionName,String packageName) {
    int permission = mContext.getPackageManager().checkPermission(permissionName,packageName);
    if (permission == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else {
        return false;
    }
}

附链接:
https://www.jianshu.com/p/a8e43ad5d7d2
https://www.cnblogs.com/xqz0618/p/aidl_service.html
https://www.cnblogs.com/androidxiaoyang/p/5919372.html

相关文章

网友评论

      本文标题:2.4 AIDL

      本文链接:https://www.haomeiwen.com/subject/eivxultx.html