上一篇: <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)>