须知少年凌云志,曾许人间第一流。这篇文章主要讲述Android binder介绍(下)相关的知识,希望能为你提供帮助。
上一篇: <
Android binder介绍(上)>
5. java Binderandroid中也实现了Java层的binder接口
主要代码如下
/framework/base/core/java/android/os/ - IInterface.java - IBinder.java - Parcel.java - IServiceManager.java - ServiceManager.java - ServiceManagerNative.java - Binder.java/framework/base/core/jni/ - android_os_Parcel.cpp - AndroidRuntime.cpp - android_util_Binder.cpp
5.1 基础类
/* * package android.os; * */ IInterface- Binder接口基类 IBinder- 远程对象接口基类 IServiceManager- ServiceManager代理接口, 继承自IInterfaceBinder- 本地Binder, 继承自IBinder, 对应native层的BnBinder BinderProxy- 远程Binder, 继承自IBinder, 对应native层的BpBinder
文章图片
5.2 ServiceManager
ServiceManager类是servicemanager在Jave层代理, 对应native层的IServiceManager
public final class ServiceManager { private static IServiceManager getIServiceManager() { }public static IBinder getService(String name) { }public static void addService(String name, IBinder service) { }public static IBinder checkService(String name) { }public static String[] listServices() { }public static void initServiceCache(Map< String, IBinder> cache) { } }ServiceManager::getIServiceManager() /* * 实际是Binder.allowBlocking(BinderInternal.getContextObject()) * 获取ServiceManagerProxy(BinderProxy) */ IBinder binder = BinderInternal.getContextObject() // JNI method in android_util_Binder.cpp android_os_BinderInternal_getContextObject() // Get a native BpBinder ProcessState::self() new ProcessState("/dev/binder") open_driver("/dev/binder") mmap() ProcessState::getContextObject(NULL) getStrongProxyForHandle(0) BpBinder::create(NULL) new BpBinder(NULL, uid) // Transform the native BpBinder to BinderProxy javaObjectForIBinder(, new BpBinder()) /* * 将Binder对象转化为IServiceManager对象 */ ServiceManagerNative.asInterface(binder) // 这里似乎没有使用 binder.queryLocalInterface("android.os.IServiceManager") // 这是实际的返回值 new ServiceManagerProxy(binder)ServiceManager::getService(name) ServiceManager::rawGetService(name) ServiceManager::getIServiceManager().getService(name) ServiceManagerProxy::getService(name) BinderProxy::transact(GET_SERVICE_TRANSACTION, , , ) // JNI method in android_util_Binder.cpp android_os_BinderProxy_transact(GET_SERVICE_TRANSACTION) BpBinder::transact(GET_SERVICE_TRANSACTION) IPCThreadState::transact(GET_SERVICE_TRANSACTION) IPCThreadState::waitForResponse() IPCThreadState::talkWithDriver() ioctl(binder_fd, BINDER_WRITE_READ, )ServiceManager::addService(name, ) ServiceManager::getIServiceManager().addService(name, ) ServiceManagerProxy::addService(name, ) BinderProxy::transact(ADD_SERVICE_TRANSACTION, , , ) ...
5.3 实例
这里介绍以下在Java framework层实现server和client的方法,以IFixMe为例
接口实现
// IFixMe.java package com.test.binder; import android.os.IInterface; import android.os.RemoteException; public interface IFixMe extends android.os.IInterface { static final int TRANSACTION_FUNC = android.os.IBinder.FIRST_CALL_TRANSACTION; static final java.lang.String DESCRIPTOR = "com.test.binder.IFixMe"; public void func(String str) throws RemoteException ; }
Server实现
// FixMe.java package com.test.binder; import android.os.Binder; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; public class FixMe extends android.os.Binder implements IFixMe{ public FixMe() { this.attachInterface(this, DESCRIPTOR); }@Override public IBinder asBinder() { return this; }public static com.test.binder.IFixMe asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iInterface = obj.queryLocalInterface(DESCRIPTOR); if (((iInterface != null) & & (iInterface instanceof com.test.binder.IFixMe))) { return ((com.test.binder.IFixMe)iInterface); } return null; }@Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_FUNC: { data.enforceInterface(DESCRIPTOR); String str = data.readString(); func1(str); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); }@Override public void func(String str) { // Do something... } }
【Android binder介绍(下)】Proxy实现
// FixMeProxy.java package com.test.binder; import android.os.IBinder; import android.os.RemoteException; public class FixMeProxy implements IFixMe { private android.os.IBinder mRemote; public FixMeProxy(android.os.IBinder remote) { mRemote = remote; }public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; }@Override public void func(String str) throws RemoteException { android.os.Parcel _data = https://www.songbingjia.com/android/android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(str); mRemote.transact(TRANSACTION_FUNC, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } }@Override public IBinder asBinder() { return mRemote; } }
测试程序
package com.test.binder; import android.os.Looper; import android.os.ServiceManager; import android.os.RemoteException; // server test demo public class ServerDemo { public static void main(String[] args) { Looper.prepareMainLooper(); android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); ServiceManager.addService("FixMe", newFixMe()); Looper.loop(); } }// client test demo public class ClientDemo { public static void main(String[] args) throws RemoteException { IBinder binder = ServiceManager.getService("FixMe"); IFixMe myService = newFixMeProxy(binder); myService.func("binder"); } }
其他实例可参考 < BinderSample>
6. AIDL从前面看出编写一个Java/C++层面的binder通信比较复杂,在Android中为了简化这种操作提出了AIDL的概念,简单来说就是按照一定的规则编写AIDL接口让编译器来自动生成Proxy和Server端相关代码
下面分别介绍一下Java和C++使用AIDL的实例
6.1 Java AIDL
在Android中使用AIDL有两种方式,一种是注册为系统服务(多在framework中使用),另一种是普通服务方式(在应用中使用);但是不管是哪种,AIDL接口定义是保持一致的。
6.1.1 AIDL接口
// IFixMe.aidl package com.test.binder; interface IFixMe { int func(String msg); }
可以使用android build-tools中的aidl工具将其转化为java代码
$ aidl.exe com/test/binder/IFixMe.aidl// IFixMe.java内容如下 interface IFixMe func() // Server端 class Stub asInterface asBinder onTransact // Proxy端 class Proxy asBinder getInterfaceDescriptor func
6.1.2 系统服务方式Server实现
import com.test.binder; public class FixMeService extends IFixMe.Stub { @Override public int func() throws android.os.RemoteException { // Do something return 0; } }
测试程序
package com.test.binder; import android.os.Looper; import android.os.ServiceManager; import android.os.RemoteException; // register server public class ServerDemo { public static void main(String[] args) { Looper.prepareMainLooper(); android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); ServiceManager.addService("FixMe", new FixMeService()); Looper.loop(); } }// client use service public class ClientDemo { public static void main(String[] args) throws RemoteException { IBinder binder = ServiceManager.getService("FixMe"); IFixMe myService = IFixMe.Stub.asInterface(binder); myService.func("binder"); } }
TIP:值得一说的是ServiceManager相关接口只能在framework中使用
6.1.3 普通服务方式Server实现
public final class FixMeService extends Service { private static final String TAG = "FixMeService"; @Override public void onCreate() { super.onCreate(); }@Override public void onDestroy() { super.onDestroy(); }@Override public int onStartCommand(Intent intent, int flags, int startId) { return START_NOT_STICKY; }@Nullable @Override public IBinder onBind(Intent intent) { return mStub; }IFixMe.Stub mStub = new IFixMe.Stub() { @Override public int func() { // Do something return 0; } }; }
客户端程序
private IFixMe mFixMe; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mFixMe = IFixMe.Stub.asInterface(service); mFixMe.func(); }@Override public void onServiceDisconnected(ComponentName name) { mFixMe = null; } }; // --- 本地调用 --- Intent intent = new Intent(this, FixMeService.class); bindService(intent, mServiceConnection, BIND_AUTO_CREATE); /* * --- 远程调用 --- * 需要在service所有的AndroidManifest.xml * * < service android:name=".FixMeService"> *< intent-filter> *< action android:name="com.test.intent.fixme"> < /action> *< /intent-filter> * < /service> */ Intent intent = new Intent(); intent.setAction("com.test.fixme"); intent.setPackage("com.test.fixmeclient"); bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
Java AIDL使用方法参考< AIDLDemo>
6.2 C++ AIDL
AIDL接口
// IFixMe.aidl package com.test.binder; interface IFixMe { int func(String msg); }
使用android build-tools中的aidl-cpp工具将其转化为C++代码
$ aidl-cpp com/test/binder/IFixMe.aidl . com/test/binder/FixMe.cpp在com/test/binder/生成如下文件 IFixMe.h class IFixMe : public android::IInterface DECLARE_META_INTERFACE(FixMe) func() BnFixMe.h class BnFixMe : public android::BnInterface< IFixMe> onTransact() BpFixMe.h class BpFixMe : public android::BpInterface< IFixMe> func() FixMe.cpp // 实现如下方法 BnFixMe::onTransact() BpFixMe::func()
Server实现
// FixMeService.h class FixMeService : public os::BnFixMe { public: int func(String msg); }// FixMeService.cpp int FixMeService::func(String msg) { // Do something return 0; }
测试程序这里不再累述,值得一说是的native层面封装了BinderService来简化添加服务的操作
可参考NetdNativeService(system/netd)和VoldNativeService(system/vold)
7. HIDL这里就不详叙了,以后有需要再添加
参考:
< Binder系列>
< Android HIDL>
< AIDL的基本使用>
< HAL接口定义语言(HIDL)>
< Android接口定义语言(AIDL)>
推荐阅读
- DCloud旗下的uni-app如何判断是否安装腾讯QQ微信微博支付宝淘宝客户端
- PyTorch如何测试感知器模型()
- PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试
- PyTorch实战(测试图像识别模型(图解分析))
- 在PyTorch中测试深层神经网络(图解)
- PyTorch如何测试卷积神经网络模型((实例图解))
- PyTorch张量介绍和用法
- PyTorch预测和线性分类使用图解
- PyTorch神经网络(感知器图解)