Android Binder通信メカニズム学習(二)
前編では,Binder通信メカニズムの基本フレームワークについて解説した.この記事では、1つの例で説明します.ネット上の友人のソースコードの共有に感謝します.ブロガーにはAndroidフレームワークの分析記事がもっとあります.
Testモジュールサービスを追加し、メソッドはtestとして一応定義します.
(1)プログラム構成
binderプログラムをコンパイルするにはbinderダイナミックリンクライブラリをリンクする必要があります.アプリケーション開発環境ではndkプログラミングを使用してbinderダイナミックリンクライブラリをリンクすることはできません.そのため、ソース開発環境では必要です.この例ではvendorディレクトリの下にサブディレクトリshuameを作成し、プロジェクトディレクトリをそのディレクトリの下に配置します.
プログラムは2つの部分から構成され、1つのbinderサービスプログラム、1つのbinderサービスをテストするclientプログラム、対応するAndroid.mkは以下の通りです.
(2)プログラムソースコード構成
Test.h:使用するヘッダファイル、宣言インタフェース、定義操作列挙、宣言binder参照クラスを含む
ITestService.cpp:インタフェースクラスメソッドの実装
TestServer.cpp:binderエンティティクラスを宣言して実装し、binderサービスを開始し、service managerに登録する
TestClient.cpp:binderリファレンスクラスを宣言して実装し、binderサービスのclientをテストする
1.サービスのインタフェースITestService(test.h)の宣言
宣言:
3.BnTestServiceインタフェースクラスの宣言を完了し、実現
宣言:
onTransact()メソッドの実装:
アーキテクチャはAndroid上のマルチメディア再生フレームワークとは少し異なり、再生インタフェースを完了する能力はClientのクラスに置かれ、マルチメディアサービスMediaPlayerService全体がClientクライアントの作成と管理を担当しています.
要するに、XXXXはBnXXXXを継承し、BnXXXXはIXXXXを継承し、BnXXXXではIXXXXを継承する虚関数は必ず実現されてからインスタンス化され、通常はXXXXで実現され、主なXXXXはインスタンス化される.
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はインスタンス化される.