Android binder介绍(下)
Posted 北落不吉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android binder介绍(下)相关的知识,希望对你有一定的参考价值。
上一篇: <Android binder介绍(上)>
5. Java Binder
android中也实现了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代理接口, 继承自IInterface Binder - 本地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... } }
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 = 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)>
以上是关于Android binder介绍(下)的主要内容,如果未能解决你的问题,请参考以下文章
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
Android课程---Android Studio使用小技巧:提取方法代码片段
千里马Android Framework实战开发-binder驱动常见binder_open,binder_mmap介绍
千里马Android Framework实战开发-binder驱动常见binder_open,binder_mmap介绍