Android Binder通信メカニズム学習(二)

4399 ワード

前編では,Binder通信メカニズムの基本フレームワークについて解説した.この記事では、1つの例で説明します.ネット上の友人のソースコードの共有に感謝します.ブロガーにはAndroidフレームワークの分析記事がもっとあります.
Testモジュールサービスを追加し、メソッドはtestとして一応定義します.
(1)プログラム構成
binderプログラムをコンパイルするにはbinderダイナミックリンクライブラリをリンクする必要があります.アプリケーション開発環境ではndkプログラミングを使用してbinderダイナミックリンクライブラリをリンクすることはできません.そのため、ソース開発環境では必要です.この例ではvendorディレクトリの下にサブディレクトリshuameを作成し、プロジェクトディレクトリをそのディレクトリの下に配置します.
プログラムは2つの部分から構成され、1つのbinderサービスプログラム、1つのbinderサービスをテストするclientプログラム、対応するAndroid.mkは以下の通りです.
LOCAL_PATH := $(call my-dir)
 
#  binder service    
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder       
LOCAL_MODULE    := TestServer
LOCAL_SRC_FILES := \
    ITestService.cpp \
    TestServer.cpp
   
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
  
#  binder service   client 
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder
LOCAL_MODULE    := TestClient
LOCAL_SRC_FILES := \
    ITestService.cpp \
    TestClient.cpp
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

(2)プログラムソースコード構成
Test.h:使用するヘッダファイル、宣言インタフェース、定義操作列挙、宣言binder参照クラスを含む
ITestService.cpp:インタフェースクラスメソッドの実装
TestServer.cpp:binderエンティティクラスを宣言して実装し、binderサービスを開始し、service managerに登録する
TestClient.cpp:binderリファレンスクラスを宣言して実装し、binderサービスのclientをテストする
1.サービスのインタフェースITestService(test.h)の宣言
	// Binder Service   test  
    class ITestService : public IInterface
    {
    public:
        DECLARE_META_INTERFACE(TestService); // declare macro
        virtual void test()=0;
    };

	//           
    enum
    {
        TEST = IBinder::FIRST_CALL_TRANSACTION,
    };
2.BpTestServiceの宣言を完了し、test実装
宣言:
	// BpXXX  IXXX,  test     ,  remote()->transact()     BnXXX::onTransaction(){ cast TEST: xxxx;}
    class BpTestService: public BpInterface<ITestService> {
    public:
    	BpTestService(const sp<IBinder>& impl);
    	virtual void test();
    };
実装:
	IMPLEMENT_META_INTERFACE(TestService, "android.TestServer.ITestService");

	void BpTestService::test() 
	{
	   printf("in the get Test
"); Parcel data, reply; data.writeInterfaceToken(ITestService::getInterfaceDescriptor()); remote()->transact(TEST, data, &reply); printf("send Print %d
", reply.readInt32()); }

3.BnTestServiceインタフェースクラスの宣言を完了し、実現
宣言:
class BnTestService: public BnInterface<ITestService> {
public:
	virtual status_t
	onTransact(uint32_t code, const Parcel& data, Parcel* reply,
			uint32_t flags = 0);
	virtual void test() {
		printf("Now get test
"); } };

onTransact()メソッドの実装:
status_t BnTestService::onTransact(uint_t code, const Parcel& data,
		Parcel* reply, uint32_t flags) {
	switch (code) {
	case TEST: {
		printf("got the client msg
"); CHECK_INTERFACE(ITest, data, reply); test(); reply->writeInt32(100); return NO_ERROR; } break; default: break; } return NO_ERROR; }
4. クライアントクライアントクライアントの実装
 int main() {
    /*  service manager  */
	sp<IServiceManager> sm = defaultServiceManager();	
	/*  test service binder    */
	sp<IBinder> binder = sm->getService(String16("service.testservice"));	
	/*  sp<ITestService>*/
	sp<ITestService> cs = interface_cast<ITestService>(binder);	
	/*  binder    test  */
    cs->test();
    return 0;
}
5.Serverエンドの実装
 int main() {
    ProcessState::self();  //     
    /*  service manager binder  */
    sp<IServiceManager> sm = defaultServiceManager(); 
    /*             String16  */
    sm->addService(String16("service.testservice"), new BnTestService());
    ProcessState::self()->startThreadPool(); //     
    IPCThreadState::self()->joinThreadPool();//      
    return 0;
}
6.コンパイル生成TestServer,TestClient,それぞれAndrlidデバイスにpushし,権限を修正し,実行してテストする
アーキテクチャはAndroid上のマルチメディア再生フレームワークとは少し異なり、再生インタフェースを完了する能力はClientのクラスに置かれ、マルチメディアサービスMediaPlayerService全体がClientクライアントの作成と管理を担当しています.
要するに、XXXXはBnXXXXを継承し、BnXXXXはIXXXXを継承し、BnXXXXではIXXXXを継承する虚関数は必ず実現されてからインスタンス化され、通常はXXXXで実現され、主なXXXXはインスタンス化される.