日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Binder实用指南(二) - 实战篇

發布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Binder实用指南(二) - 实战篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本章的內容主要說明如何在JavaFramework層和Native層自定義Client-Server組件,并且使用Binder進行通信。

一、Native Binder

源碼目錄結構:

alps/frameworks/native/cmds/NativeBinderDemo/

123456 |-NativeBinderDemo|---ClientDemo.cpp: 客戶端程序|---ServerDemo.cpp:服務端程序|---IMyService.h:自定義的MyService服務的頭文件|---IMyService.cpp:自定義的MyService服務|---Android.mk:源碼build文件

1.1 服務端

alps/frameworks/native/cmds/NativeBinderDemo/ServerDemo.cpp

獲取ServiceManager,注冊service.myservice服務到ServiceManager,啟動服務。

123456789 #include "IMyService.h"int main() {sp < IServiceManager > sm = defaultServiceManager(); //獲取service manager引用sm->addService(String16("service.myservice"), new BnMyService()); //注冊名為"service.myservice"的服務到service managerProcessState::self()->startThreadPool(); //啟動線程池IPCThreadState::self()->joinThreadPool(); //把主線程加入線程池 return 0;}

1.2 客戶端

alps/frameworks/native/cmds/NativeBinderDemo/ClientDemo.cpp

獲取ServiceManager,拿到service.myservice服務,再進行類型轉換成IMyService,最后調用遠程方法sayHello()

123456789 #include "IMyService.h"int main() {sp < IServiceManager > sm = defaultServiceManager(); //獲取service manager引用sp < IBinder > binder = sm->getService(String16("service.myservice"));//獲取名為"service.myservice"的binder接口sp<IMyService> cs = interface_cast < IMyService > (binder);//將biner對象轉換為強引用類型的IMyServicecs->sayHello();//利用binder引用調用遠程sayHello()方法 return 0;}

1.3 MyService

alps/frameworks/native/cmds/NativeBinderDemo/IMyService.h

申明IMyService,申明BpMyService(Binder客戶端),申明BnMyService(Binder的服務端)。

123456789101112131415161718192021222324252627282930313233343536373839404142 #ifndef MY_SERVICE_DEMO#define MY_SERVICE_DEMO#include <stdio.h>#include <binder/IInterface.h>#include <binder/Parcel.h>#include <binder/IBinder.h>#include <binder/Binder.h>#include <binder/ProcessState.h>#include <binder/IPCThreadState.h>#include <binder/IServiceManager.h>using namespace android;namespace android{ class IMyService : public IInterface{ public:DECLARE_META_INTERFACE(MyService); //使用宏,申明MyService virtual void sayHello()=0; //定義方法}; //定義命令字段 enum{HELLO = 1,}; //申明客戶端BpMyService class BpMyService: public BpInterface<IMyService> { public:BpMyService(const sp<IBinder>& impl); virtual void sayHello();}; //申明服務端BnMyService class BnMyService: public BnInterface<IMyService> { public: virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); virtual void sayHello();};}#endif

alps/frameworks/native/cmds/NativeBinderDemo/IMyService.cpp

123456789101112131415161718192021222324252627282930313233343536373839404142 #include "IMyService.h"namespace android{IMPLEMENT_META_INTERFACE(MyService, "android.demo.IMyService"); //使用宏,完成MyService定義 //客戶端BpMyService::BpMyService(const sp<IBinder>& impl) :BpInterface<IMyService>(impl) {} // 實現客戶端sayHello方法 void BpMyService::sayHello() { printf("BpMyService::sayHello\n");Parcel data, reply;data.writeInterfaceToken(IMyService::getInterfaceDescriptor());remote()->transact(HELLO, data, &reply); printf("get num from BnMyService: %d\n", reply.readInt32());} //服務端,接收遠程消息,處理onTransact方法 status_t BnMyService::onTransact(uint_t code, const Parcel& data,Parcel* reply, uint32_t flags) { switch (code) { case HELLO: { //收到HELLO命令的處理流程 printf("BnMyService:: got the client hello\n");CHECK_INTERFACE(IMyService, data, reply);sayHello();reply->writeInt32(2015); return NO_ERROR;} break; default: break;} return NO_ERROR;} // 實現服務端sayHello方法 void BnMyService::sayHello() { printf("BnMyService::sayHello\n");};}

1.4 Android.mk

12345678910111213141516171819202122232425262728 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)LOCAL_SHARED_LIBRARIES := \libcutils \libutils \libbinder LOCAL_MODULE := ServerDemoLOCAL_SRC_FILES := \IMyService.cpp \ServerDemo.cpp LOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE) include $(CLEAR_VARS)LOCAL_SHARED_LIBRARIES := \libcutils \libutils \libbinderLOCAL_MODULE := ClientDemoLOCAL_SRC_FILES := \IMyService.cpp \ClientDemo.cppLOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)

1.5 原理圖

1.6 運行

編譯:
mm alps/frameworks/native/cmds/NativeBinderDemo目錄,然后到alps/out/target/product/{Project}/system/bin/會生成ClientDemo和ServerDemo

執行:

123 adb remountadb push ServerDemo /system/binadb push ClientDemo /system/bin

開兩個窗口分別執行下面兩個命令便可以看到結果了:
adb shell system/bin/ServerDemo?,?adb shell system/bin/ClientDemo

二、JavaFramework Binder

源碼目錄結構:

alps/frameworks/base/cmds/FrameworkBinderDemo/

12345678 |-Server端|---ServerDemo.java:可執行程序|---IMyService.java: 定義IMyService接口|---MyService.java:定義MyService|-Client端|---ClientDemo.java:可執行程序|---IMyService.java: 與Server端完全一致|---MyServiceProxy.java:定義MyServiceProxy

2.1 Server端

(1)ServerDemo.java

可執行程序

123456789101112 public class ServerDemo { public static void main(String[] args) {System.out.println("MyService Start"); //準備Looper循環執行Looper.prepareMainLooper(); //設置為前臺優先級android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); //注冊服務ServiceManager.addService("MyService", new MyService());Looper.loop();}}

(2)IMyService.java

定義sayHello()方法,DESCRIPTOR屬性

12345 public interface IMyService extends IInterface { static final java.lang.String DESCRIPTOR = "com.yuanhh.frameworkBinder.MyServer"; public void sayHello(String str) throws RemoteException ; static final int TRANSACTION_say = android.os.IBinder.FIRST_CALL_TRANSACTION;}

(3)MyService.java

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 public class MyService extends Binder implements IMyService{ public MyService() { this.attachInterface(this, DESCRIPTOR);} @Override public IBinder asBinder() { return this;} /** 將MyService轉換為IMyService接口 **/ public static com.yuanhh.frameworkBinder.IMyService asInterface(android.os.IBinder obj) { if ((obj == null)) { return null;}android.os.IInterface iInterface = obj.queryLocalInterface(DESCRIPTOR); if (((iInterface != null)&&(iInterface instanceof com.yuanhh.frameworkBinder.IMyService))){ return ((com.yuanhh.frameworkBinder.IMyService) iInterface);} return null;} /** 服務端,接收遠程消息,處理onTransact方法 **/ @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_say: {data.enforceInterface(DESCRIPTOR);String str = data.readString();sayHello(str);reply.writeNoException(); return true;}} return super.onTransact(code, data, reply, flags);} /** 自定義sayHello()方法 **/ @Override public void sayHello(String str) {System.out.println("MyService:: Hello, " + str);}}

(4) Android.mk

12345678910111213141516 LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := $(call all-subdir-java-files)LOCAL_MODULE := ServerDemo LOCAL_MODULE_TAGS := optionalinclude $(BUILD_JAVA_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := ServerDemoLOCAL_MODULE_TAGS := optionalLOCAL_MODULE_PATH := $(TARGET_OUT)/binLOCAL_MODULE_CLASS := UTILITY_EXECUTABLESLOCAL_SRC_FILES := ServerDemoinclude $(BUILD_PREBUILT)

(5) ServerDemo

123 base=/systemexport CLASSPATH=$base/framework/ServerDemo.jarexec app_process $base/bin com.shun.frameworkBinder.ServerDemo "$@"

2.2 Client端

(1)ClientDemo.java

可執行程序

12345678910 public class ClientDemo { public static void main(String[] args) throws RemoteException {System.out.println("Client start");IBinder binder = ServiceManager.getService("MyService"); //獲取名為"MyService"的服務IMyService myService = new MyServiceProxy(binder); //創建MyServiceProxy對象myService.sayHello("binder"); //通過MyServiceProxy對象調用接口的方法System.out.println("Client end");}}

(2)IMyService.java

與Server端的IMyService是一致,基本都是拷貝一份過來。

(3)MyServiceProxy.java

1234567891011121314151617181920212223242526272829303132 public class MyServiceProxy implements IMyService { private android.os.IBinder mRemote; //代表BpBinder public MyServiceProxy(android.os.IBinder remote) {mRemote = remote;} public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR;} /** 自定義的sayHello()方法 **/ @Override public void sayHello(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_say, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}} @Override public IBinder asBinder() { return mRemote;}}

(4) Android.mk

123456789101112131415 LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := $(call all-subdir-java-files)LOCAL_MODULE := ClientDemo LOCAL_MODULE_TAGS := optionalinclude $(BUILD_JAVA_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := ClientDemoLOCAL_MODULE_TAGS := optionalLOCAL_MODULE_PATH := $(TARGET_OUT)/binLOCAL_MODULE_CLASS := UTILITY_EXECUTABLESLOCAL_SRC_FILES := ClientDemoinclude $(BUILD_PREBUILT)

(5) ClientDemo

123 base=/systemexport CLASSPATH=$base/framework/ClientDemo.jarexec app_process $base/bin com.shun.frameworkBinder.ClientDemo "$@"

2.3 原理圖

2.4 運行

編譯:

mm alps/frameworks/base/cmds/FrameworkBinderDemo/目錄,然后:
alps/out/target/product/{Project}/system/bin/ 生成ClientDemo和ServerDemo
alps/out/target/product/{Project}/system/framework/ 生成ClientDemo.jar和ServerDemo.jar。

執行:

12345 adb remountadb push ServerDemo /system/binadb push ClientDemo /system/binadb push ServerDemo.jar /system/framework/adb push ClientDemo.jar /system/framework/

開兩個窗口分別執行下面兩個命令便可以看到結果了:
adb shell system/bin/ServerDemo , adb shell system/bin/ClientDemo

原文地址:?https://maoao530.github.io/2016/12/25/android-binder-02/

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的Binder实用指南(二) - 实战篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。