android binder机制简单使用

需求

    最近公司需要在native层写一个c++服务,用来与上层通讯,由于自己并不是很精通c++,所以决定从简单的入手,先尝试写一个binder服务。


具体实现

    实现一个binder通信实例,需要经过以下步骤:
        1、获得ServiceManager的对象引用
        2、向ServiceManager注册新的Service
        3、在Client中通过ServiceManager获得Service对象引用
        4、在Client中发送请求,由Service返回结果。

具体代码:

1、编写myservic.h文件

#include <utils/threads.h>
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/BpBinder.h>
#include <binder/Parcel.h>

namespace android {
    class MyService : public BBinder    
    {
        mutable Mutex mLock;
        int32_t mNextConnId;
        public:
            static int instantiate();
            MyService();
            virtual ~MyService();
            virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
    };
}; //namespace
2、编写myservice.cpp文件
#include "myservice.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
  
namespace android {
    static struct sigaction oldact;
    static pthread_key_t sigbuskey;

    int MyService::instantiate()    
    {
        LOGE("MyService instantiate");
        // defaultServiceManager ()获得ServiceManager的对象引用,addService()可向ServiceManager注册新的服务
        int r = defaultServiceManager()->addService(String16("android.myservice"), new MyService());
        LOGE("MyService r = %d/n", r);
        return r;
    }

    MyService::MyService()
    {
        LOGV("MyService created");
        mNextConnId = 1;
        pthread_key_create(&sigbuskey, NULL);
    }

    MyService::~MyService()
    {
        pthread_key_delete(sigbuskey);
        LOGV("MyService destroyed");
    }    

    // 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数,该函数分析接收到的数据包,调用相应的接口函数处理请求
    status_t MyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
        switch(code)
        {
            case 0: {
                pid_t pid = data.readInt32();
                int num   = data.readInt32();
                num = num + 100;
                reply->writeInt32(num);
                return NO_ERROR;
                }
                break;
            default:
                return BBinder::onTransact(code, data, reply, flags);
        }
    }
}; //namespace 
3、编写Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := myservice.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := libutils libbinder
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libmyservice
include $(BUILD_SHARED_LIBRARY)

mk文件写完之后进行编译,编译完生成libmyservice.so文件。

4、编写myserver.cpp文件与相应的mk文件

#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <private/android_filesystem_config.h>
#include "../libmyservice/myservice.h"

using namespace android;
  
int main(int argc, char** argv)
{
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();//获得ServiceManager接口
    LOGI("ServiceManager: %p", sm.get());
    MyService::instantiate();    
    //执行addService()函数,注册服务  
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    //进入循环,等待客户端的请求  
    return 0;    
}

mk文件:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
    myserver.cpp  

LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
    libutils libbinder libmyservice  

LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := myserver
include $(BUILD_EXECUTABLE)
编译生成可执行文件myserver。5、编写myclient.h文件
namespace android
{
    class MyClient {
    public:
        void add100(int n);
        private:
        static const void getMyService();  
        //通过ServiceManager获取服务接口  
    };
}; //namespace
6、编写myclient.cpp文件
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "myclient.h"
  
namespace android
{
    sp<IBinder> binder;
    void MyClient::add100(int n)
    {
        getMyService();
        Parcel data, reply;
        int answer;
        data.writeInt32(getpid());
        data.writeInt32(n);
        LOGE("BpMyService::create remote()->transact()/n");
        binder->transact(0, data, &reply);
        answer = reply.readInt32();
        printf("answner=%d/n", answer);
        return;
    }

    const void MyClient::getMyService()
    {
        sp<IServiceManager> sm = defaultServiceManager();
        binder = sm->getService(String16("android.myservice")); 
        LOGE("MyClient::getMyService %p/n",sm.get());
        if (binder == 0) {
            LOGW("MyService not published, waiting...");
            return;
        }
    }
}; //namespace

using namespace android;

int main(int argc, char** argv)
{
    MyClient* p = new MyClient();  
    p->add100(1);
    return 0;
}
7、编写client端的Android.mk文件
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
    myclient.cpp  

LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
    libutils libbinder libmyservice  

LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := myclient

include $(BUILD_EXECUTABLE)
写完之后编译生成myclient可执行文件。


一个binder的服务端与客户端的例子就写好了,生成的so文件push到system/lib/下面,两个可执行文件push到system/bin/目录下。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值