android本地服务

这篇文章根据最近工作上对安卓本地服务的理解,同时也参考了其他人的文章,自己按照相同的框架做了一个diyservice,代码很简单,由此先记下:

服务器端:

头文件:diyservice.h

#ifndef __DIY_SERVICE_H__
#define __DIY_SERVICE_H__
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/threads.h>
namespace android
{
//定义接口同时用于客户端和服务端
class IDiyService: public IInterface
{
public:
    DECLARE_META_INTERFACE(DiyService);
    virtual int getNumber(int arg0) = 0;
};

//定义服务端代码 用于继承
class BnDiyService: public BnInterface<IDiyService>
{
public:
   virtual status_t onTransact( uint32_t code,
                                   const Parcel& data,
                                   Parcel* reply,
                                   uint32_t flags = 0);
};

//定义交互的内容
enum 
{
    GET_NUMBER = IBinder::FIRST_CALL_TRANSACTION,
};

class BpDiyService: public BpInterface<IDiyService>
{
public:
//这个构造函数的参数impl就是remote的来历。具体要看BpInterface
   BpDiyService(const sp<IBinder>& impl): BpInterface<IDiyService>(impl)
   {
   }
   int getNumber(int arg0)
   {
        Parcel data;
        Parcel reply;
        data.writeInt32(arg0);
        remote()->transact(GET_NUMBER, data, &reply);
        return reply.readInt32();
   }
};
//实现了IDiyService的asinterface函数,这个函数其实是使用得到的Bpbinder对象作为参数来创建BpDiyService对象。
IMPLEMENT_META_INTERFACE(DiyService, "android.DiyService.IDiyService");
//服务端实现类,具体实现在下面的cpp里面
class diyservice:public BnDiyService
{
public:
int getNumber(int arg0);
};
}
#endif

CPP文件:diyservice.cpp

#include <cutils/log.h>
#include <cutils/properties.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "diyservice.h"
namespace android
{
//实现服务端如何处理客户端提交过来的请求。这里主要涉及到Parcel这个结构体的使用方法。
        status_t BnDiyService::onTransact(uint32_t code, const Parcel&data, Parcel*reply, uint32_t flags)
	{  
                int ret = 0;
                switch(code) 
                {  
                case GET_NUMBER:
                        ret = getNumber(data.readInt32());
                        reply->writeInt32(ret);
                        return NO_ERROR;  
                        break;
                }  
                return NO_ERROR;
        }
        //没有更多作用,只是实现IDiyService接口的这个虚函数。
        int diyservice::getNumber(int arg0)
        {
                return arg0;
        } 
}


对应的Android.mk

LOCAL_PATH:= $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES:= diyservice.cpp
 
LOCAL_SHARED_LIBRARIES:= libutils libutils libbinder
 
LOCAL_C_INCLUDES := $(TOP)/frameworks/base/include
LOCAL_MODULE_TAGS := optional


LOCAL_MODULE:= libdiyservice
 
LOCAL_PRELINK_MODULE:= false
 
include $(BUILD_SHARED_LIBRARY)

注意这里是编译成了LIB库文件。

下面是这个服务器的进行代码:

main.cpp

#include <cutils/log.h>
#include <cutils/properties.h>
#include <sys/types.h>
#include <unistd.h>
#include <cutils/log.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "../diyservice.h"
using namespace android;
int main()  
{  
        sp<ProcessState> proc(ProcessState::self());  
        //得到ServiceManager,其实它也是一个服务。只是服务端在内核中。
        sp<IServiceManager> sm = defaultServiceManager();  
        //调用它的addService接口添加我们刚定义的服务到ServiceManager.
        sm->addService(String16("service.diysvc"),new diyservice());  
        //最后两个其实就对内核设备节点进行一个poll的过程,一直等待内核数据的到来。
        ProcessState::self()->startThreadPool();  
        IPCThreadState::self()->joinThreadPool();  
} 


对应的Android.mk

LOCAL_PATH:= $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES:= main.cpp
 
LOCAL_SHARED_LIBRARIES:= libutils libdiyservice libbinder
LOCAL_MODULE_TAGS := optional


LOCAL_MODULE:= diytest
 
include $(BUILD_EXECUTABLE)

客户端程序:

testService.cpp

#include <cutils/log.h>
#include <cutils/properties.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/BpBinder.h>
#include "../diyservice.h"

using namespace android;
int main(int argc,char *argv[])
{
        sp<IBinder> TestAbinder;
        Parcel data, reply;
        int send;
	int sum=0;
        if(argc < 2)
              return 0;
        send = atoi(argv[1]);
        LOGI("testService main is call...");
        //首先还是要取得SensorManger这个中间人。
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IDiyService> Diy_service;
        while(1)
        {
                //然后调用它的getService,这个函数会到内核去查询属于我们要的service的句柄,然后通过这个句柄建立Bpbinder对象。
                TestAbinder = sm->getService(String16("service.diysvc"));
                LOGE("TestA::getAddService %p/n",sm.get());
                if (TestAbinder == 0)
                {
                        LOGE("TestAService not published, waiting...");
                        usleep(1000000);
                        continue;
                }
                else
                {
                        LOGI("TestA::getAddService success...");
                        break;
                }
         }
        printf("handle:%d\n",((BpBinder *)(TestAbinder.get()))->handle());
        //有了这个对象后再调用IDiyService的asInterface对象后,会产生BpDiyService这个对象,然后返回。
        Diy_service = interface_cast<IDiyService>(TestAbinder);
        //最后调用BpDiyService的getNumber函数,这个函数会具体的向内核发出请求,并得到响应。
        sum = Diy_service->getNumber(send);
        LOGI("GET_NUMBER value = %d",sum);
        return 0;
}


对应的Android.mk

LOCAL_PATH:= $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES:= testService.cpp
 
LOCAL_SHARED_LIBRARIES:= libutils libdiyservice libbinder
LOCAL_MODULE_TAGS := optional


LOCAL_MODULE:= testdiyService
 
include $(BUILD_EXECUTABLE)

编译好后通过adb push到安卓手机后就可以运行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值