Weitere ähnliche Inhalte
Ähnlich wie Binderのはじめの一歩とAndroid (20)
Kürzlich hochgeladen (10)
Binderのはじめの一歩とAndroid
- 7. Binderの歴史
● 元々はNext Generation BeOSに採用される予定だった
OpenBinder。(http://www.angryredplanet.
com/~hackbod/openbinder/)
● UNIXのCORBA、WindowsのCOMのように分散コンポーネント
環境を提供するフレームワーク。
● BeOSポシャっちゃったので残念ながら動くものとしては採用され
ず。
● OpenBinderをメンテしていたHackbornさんは今はAndroidのプ
ラットフォームエンジニア。よくGroupに投稿しています。
● 余談ですがBeの創業者Gasseeも、Danger、Androidの創業者
Andy Rubinも元Apple。Appleすごいですね。
- 12. 実際に使ってみる 受信側
● main.cpp 受信側起動処理 SurfaceFlingerやAudioFlingerな
どが参考になります。
#define LOG_TAG "RECEIVER"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include "receiver.h"
int main(int argc, char** argv) {
LOGD("Reciever start.");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGD("ServiceManager: %p", sm.get());
Receiver::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
- 13. 実際に使ってみる 受信側
● receiver.h BBinderを継承した受信処理クラスの定義
#ifndef RECEIVER_H_
#define RECEIVER_H_
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
using namespace android;
class Receiver:public BBinder {
public:
static void instantiate();
Receiver();
virtual ~Receiver();
virtual status_t onTransact(
uint32_t, const Parcel&, Parcel*, uint32_t);
};
#endif /* RECEIVER_H_ */
- 14. 実際に使ってみる 受信側
● receiver.cpp Receiverクラスの実装。受けた数値を5倍して返
す。
#define LOG_TAG "RECEIVER"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <utils/Log.h>
#include "receiver.h"
using namespace android;
void Receiver::instantiate() {
defaultServiceManager()->addService(
String16("Receiver"), new Receiver());
}
Receiver::Receiver() {
LOGD("Receiver created.n");
}
Receiver::~Receiver() {
LOGD("Receiver destroyed.n");
}
- 15. 実際に使ってみる 受信側
● receiver.cpp 続き BBinder::onTransactの実装部分
status_t Receiver::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
LOGD("Message received code=%d.n", code);
pid_t pid;
int num;
switch(code) {
case 0:
pid = data.readInt32();
LOGD("Sender pid=%d", pid);
num = data.readInt32();
LOGD("Number Data=%dn",num);
reply->writeInt32(num*5);
break;
default:
//do nothing.
break;
}
return NO_ERROR;
}
- 16. 実際に使ってみる 送信側
● receiver.cpp 送信処理。自プロセスIDと数値の12を送信する。
#define LOG_TAG "SENDER"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/RefBase.h>
#include <utils/Log.h>
using namespace android;
int main() {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("Receiver"));
LOGD("Sender getService %pn",sm.get());
if (binder == NULL) {
LOGE("Receiver Service not found.n");
return -1;
}
- 17. 実際に使ってみる 送信側
● receiver.cpp 続き。実際の送信処理部分。
Parcel data, reply;
pid_t pid = getpid();
LOGD("pid=%d", pid);
data.writeInt32(pid);
int num = 12;
LOGD("num=%d", num);
data.writeInt32(num);
//非同期メッセージはFLAG_ONEWAYを4番目に追加
binder->transact(0, data, &reply);
LOGD("reply num=%d", reply.readInt32());
return NO_ERROR;
}
- 21. 実行結果のログ
D/RECEIVER( 286): Reciever start.
D/RECEIVER( 286): ServiceManager: 0xb678
D/RECEIVER( 286): Receiver created.
D/SENDER ( 288): Sender getService 0xa678
D/SENDER ( 288): pid=288
D/SENDER ( 288): num=12
D/RECEIVER( 286): Message received code=0.
D/RECEIVER( 286): Sender pid=288
D/RECEIVER( 286): Number Data=12
D/SENDER ( 288): reply num=60