sunwengang blog

developer | android display/graphics

  1. 1. 文件目录
  2. 2. cmds/helloWorld/Android.mk
  3. 3. cmds/helloWorld/BpHelloWorldService.h
  4. 4. cmds/helloWorld/BnHelloWorldService.h
  5. 5. cmds/helloWorld/HelloWorldService.h
  6. 6. cmds/helloWorld/IHelloWorldService.h
  7. 7. cmds/helloWorld/main_helloworldclient.cpp
  8. 8. cmds/helloWorld/main_helloworldservice.cpp
  9. 9. libs/helloWorld/Android.bp
  10. 10. libs/helloWorld/BnHelloWorldService.h
  11. 11. libs/helloWorld/BnHelloWorldService.cpp
  12. 12. libs/helloWorld/BpHelloWorldService.h
  13. 13. libs/helloWorld/BpHelloWorldService.cpp
  14. 14. libs/helloWorld/HelloWorldService.h
  15. 15. libs/helloWorld/HelloWorldService.cpp
  16. 16. libs/helloWorld/IHelloWorldService.h
  17. 17. libs/helloWorld/IHelloWorldService.cpp

Binder通信是Android用的比较多的一种通信机制,它是一种client-server的通信结构。Binder通信具有以下特点:

  1. 用驱动程序来推进进程间的通信;
  2. 可以通过共享内存的方式来提供性能;
  3. 可以为进程请求分配每个进程的线程池;
  4. 针对系统中的对象引入了引用计数和跨进程的对象引用映射;
  5. 可以方便的进行进程同步调用。

以下简单的Binder实例参考一位大佬。

文件目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cmds/helloWorld/Android.mk                 | 29 +++++++++++++++++++++++
cmds/helloWorld/BnHelloWorldService.h | 16 +++++++++++++
cmds/helloWorld/BpHelloWorldService.h | 12 ++++++++++
cmds/helloWorld/HelloWorldService.h | 17 +++++++++++++
cmds/helloWorld/IHelloWorldService.h | 21 +++++++++++++++++
cmds/helloWorld/main_helloworldclient.cpp | 36 ++++++++++++++++++++++++++++
cmds/helloWorld/main_helloworldservice.cpp | 22 +++++++++++++++++
libs/helloWorld/Android.bp | 38 ++++++++++++++++++++++++++++++
libs/helloWorld/BnHelloWorldService.cpp | 24 +++++++++++++++++++
libs/helloWorld/BnHelloWorldService.h | 16 +++++++++++++
libs/helloWorld/BpHelloWorldService.cpp | 25 ++++++++++++++++++++
libs/helloWorld/BpHelloWorldService.h | 12 ++++++++++
libs/helloWorld/HelloWorldService.cpp | 33 ++++++++++++++++++++++++++
libs/helloWorld/HelloWorldService.h | 17 +++++++++++++
libs/helloWorld/IHelloWorldService.cpp | 8 +++++++
libs/helloWorld/IHelloWorldService.h | 21 +++++++++++++++++

cmds/helloWorld/Android.mk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Copyright 2019 The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := main_helloworldservice.cpp

LOCAL_SHARED_LIBRARIES :=\
libutils \
libbinder \
libhelloworld

base := $(LOCAL_PATH)/../../libs/helloWorld

LOCAL_MODULE := helloworldservice
include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := main_helloworldclient.cpp

LOCAL_SHARED_LIBRARIES :=\
libutils \
libbinder \
libhelloworld

base := $(LOCAL_PATH)/../../libs/helloWorld

LOCAL_MODULE := helloworldclient //编译结果so文件
include $(BUILD_EXECUTABLE)

cmds/helloWorld/BpHelloWorldService.h

客户端Service头文件,声明BpHelloWorldService函数

1
2
3
4
5
6
7
8
9
10
11
#include <binder/Parcel.h>
#include <IHelloWorldService.h>

namespace android{
class BpHelloWorldService: public BpInterface<IHelloWorldService>
{
public:
BpHelloWorldService (const sp<IBinder>& impl);
virtual status_t helloWorld(const char *str);
};
};

cmds/helloWorld/BnHelloWorldService.h

Bn服务端Service头文件,声明onTranscat接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef ANDROID_BNHELLOWORLD_H
#define ANDROID_BNHELLOWORLD_H

#include <binder/Parcel.h>
#include <IHelloWorldService.h>

namespace android {
class BnHelloWorldService : public BnInterface<IHelloWorldService>
{
public:
virtual status_t onTransact ( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0 );
};
};
#endif

cmds/helloWorld/HelloWorldService.h

Bn服务端实现类的头文件,声明helloworldonTransact函数,和私有类构造函数和析构函数
和另一个库的文件同名,继承Bn服务端接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <BnHelloWorldService.h>
#include <utils/Log.h>

namespace android {
class HelloWorldService : public BnHelloWorldService
{
public:
static void instantiate();
virtual status_t helloWorld(const char *str);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
private:
HelloWorldService();
virtual ~HelloWorldService();
};
};

cmds/helloWorld/IHelloWorldService.h

Bp和Bn端的中间接口头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef ANDROID_HELLOWORLD_H
#define ANDROID_HELLOWORLD_H

#include <binder/IInterface.h>

namespace android {

enum {
HW_HELLOWORLD = IBinder::FIRST_CALL_TRANSACTION,
};

class IHelloWorldService: public IInterface {

public:
DECLARE_META_INTERFACE(HelloWorldService);
virtual status_t helloWorld(const char *str) = 0;
};
};

#endif

cmds/helloWorld/main_helloworldclient.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define LOG_TAG "main_helloworldclient"

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

#include <utils/Log.h>
#include <utils/RefBase.h>
#include <IHelloWorldService.h>

using namespace android;
#define unused(x) x=x

int main(int argc, char *argv[])
{
//ALOGI("HelloWorldService client is now starting");
unused(argc);
unused(argv);

sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> b;
sp<IHelloWorldService> sHelloWorldService;

do {
b = sm->getService(String16(
"android.apps.IHelloWorldService"));
if (b!=0)
break;
//ALOGI("helloworldservice is not working, waiting ...");
usleep(500000);
} while(true);

sHelloWorldService = interface_cast<IHelloWorldService>(b);
sHelloWorldService -> helloWorld("hello, world");

return(0);
}

cmds/helloWorld/main_helloworldservice.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>

#include <IHelloWorldService.h>
#include <HelloWorldService.h>

using namespace android;
#define unused(x) x=x
int main(int argc, char *argv[])
{
unused(argc);
unused(argv);
HelloWorldService::instantiate();
ProcessState::self()->startThreadPool();
//ALOGI("HelloWorldService is starting now");
//ALOGI("HelloWorldService is starting now tempChar = %s", tempChar);
IPCThreadState::self()->joinThreadPool();
return 0;
}

libs/helloWorld/Android.bp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Copyright (C) 2010 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
cc_library_shared {
name: "libhelloworld",
srcs: [
"BnHelloWorldService.cpp",
"BpHelloWorldService.cpp",
"HelloWorldService.cpp",
"IHelloWorldService.cpp",
],

shared_libs: [
"libcutils",
"liblog",
"libutils",
"libbinder",
],

include_dirs: ["frameworks/base/cmds"], //上面创建的库

cflags: [
"-Wall",
"-Wextra",
"-Werror",
],

}

libs/helloWorld/BnHelloWorldService.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef ANDROID_BNHELLOWORLD_H
#define ANDROID_BNHELLOWORLD_H

#include <binder/Parcel.h>
#include <IHelloWorldService.h>

namespace android {
class BnHelloWorldService : public BnInterface<IHelloWorldService>
{
public:
virtual status_t onTransact ( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0 );

};
};
#endif

libs/helloWorld/BnHelloWorldService.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <BnHelloWorldService.h>
#include <binder/Parcel.h>

namespace android {

status_t BnHelloWorldService::onTransact(uint32_t code,
const Parcel &data,
Parcel *reply,
uint32_t flags)
{
switch(code) {
case HW_HELLOWORLD: {
CHECK_INTERFACE(IHelloWorldService, data, reply); //检查接口
const char *str;
str = data.readCString(); //读取数据
reply-> writeInt32(helloWorld(str)); //写入数据
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags); //服务端接口接收数据
}

}
}

libs/helloWorld/BpHelloWorldService.h

1
2
3
4
5
6
7
8
9
10
11
12
#include <binder/Parcel.h>
#include <IHelloWorldService.h>

namespace android{
class BpHelloWorldService: public BpInterface<IHelloWorldService>
{
public:
BpHelloWorldService (const sp<IBinder>& impl);
virtual status_t helloWorld(const char *str);
};

};

libs/helloWorld/BpHelloWorldService.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <binder/Parcel.h>
#include <BpHelloWorldService.h>
#include <utils/Log.h>

namespace android{

status_t BpHelloWorldService::helloWorld(const char *str) {
Parcel data, reply;
data.writeInterfaceToken(
IHelloWorldService::getInterfaceDescriptor());
data.writeCString(str); //写入数据
status_t status = remote()->transact(HW_HELLOWORLD, data, &reply); //远程传输数据
if (status != NO_ERROR) {
ALOGI("print helloworld error : %s", strerror(-status));
} else {
status = reply.readInt32(); //读取数据
}
return status;
}

BpHelloWorldService::BpHelloWorldService (const sp<IBinder>& impl)
: BpInterface<IHelloWorldService>(impl)
{}

};

libs/helloWorld/HelloWorldService.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <BnHelloWorldService.h>
#include <utils/Log.h>

namespace android {
//继承Bn服务端
class HelloWorldService : public BnHelloWorldService
{
public:
static void instantiate();
virtual status_t helloWorld(const char *str);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
private:
HelloWorldService();
virtual ~HelloWorldService();
};
};

libs/helloWorld/HelloWorldService.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <BnHelloWorldService.h>
#include <HelloWorldService.h>
#include <utils/Log.h>

namespace android {
void HelloWorldService::instantiate() {
defaultServiceManager()->addService(
String16("android.apps.IHelloWorldService"), new HelloWorldService());
}

status_t HelloWorldService::helloWorld(const char* str) {
ALOGI("%s\n", str);
printf("%s\n", str);
return NO_ERROR;
}

HelloWorldService::HelloWorldService(){
ALOGI("HelloWorldService is created");
}

HelloWorldService::~HelloWorldService(){
ALOGI("HelloWorldService is destroyed");
}

status_t HelloWorldService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
return BnHelloWorldService::onTransact(code, data, reply, flags);
}

};

libs/helloWorld/IHelloWorldService.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef ANDROID_HELLOWORLD_H
#define ANDROID_HELLOWORLD_H

#include <binder/IInterface.h>

namespace android {

enum {
HW_HELLOWORLD = IBinder::FIRST_CALL_TRANSACTION,
};

class IHelloWorldService: public IInterface {

public:
DECLARE_META_INTERFACE(HelloWorldService);
virtual status_t helloWorld(const char *str) = 0;
};
};

#endif

libs/helloWorld/IHelloWorldService.cpp

1
2
3
4
5
6
7
8
#include <IHelloWorldService.h>
#include <BpHelloWorldService.h>

namespace android {

IMPLEMENT_META_INTERFACE(HelloWorldService, "android.apps.IHelloWorldService");

};

本文作者 : sunwengang
本文使用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
本文链接 : https://alonealive.github.io/Blog/2019/11/24/2019/191124_android_binder_example/

本文最后更新于 天前,文中所描述的信息可能已发生改变