Firefly开源社区

标题: (代码流)制作Native服务 [打印本页]

作者: bunchen    时间: 2014-10-21 10:15
标题: (代码流)制作Native服务
制作Native服务很简单,主要有两个步骤:1.创建服务。2.把服务加入到Android系统的ServiceManager。
一、首先,创建服务。创建Natvie服务,我们可以新建一个集成自BBinder的类。BBinder类是一个抽象类,是android进程间通信的工具,我们要实现这个方法来实现我们的功能:
virtual status_t onTransact(uint32_t , const Parcel& , Parcel* , uint32_t);
因此,我们创建一个Nativie服务叫MyService
  1. #ifndef __MYSERVICE_H__
  2. #define __MYSERVICE_H__

  3. #include <utils/RefBase.h>
  4. #include <binder/IInterface.h>
  5. #include <binder/Parcel.h>

  6. namespace android
  7. {
  8.         class MyService : public BBinder
  9.         {
  10.         public :
  11.                 static int Instance();
  12.                 MyService();
  13.                 virtual ~MyService();
  14.                 virtual status_t onTransact(uint32_t , const Parcel& , Parcel* , uint32_t);
  15.         };
  16. }

  17. #endif
复制代码

实现MyService的功能:
  1. #include <binder/IServiceManager.h>
  2. #include <binder/IPCThreadState.h>
  3. #include "MyService.h"


  4. #define DEBUG 1

  5. #if DEBUG
  6. #define LOG_TAG "MyService"
  7. #endif

  8. #include <utils/Log.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11.        
  12. namespace android
  13. {
  14.         static pthread_key_t sigbuskey;
  15.         int MyService::Instance()
  16.         {       
  17.                 if(DEBUG) ALOGD("MyService Instantiate\n");
  18.                 int ret = defaultServiceManager()->addService(String16("tchip.MyService"),new MyService());
  19.                
  20.                 if(DEBUG) ALOGD("MyService ret = %d\n",ret);
  21.                
  22.                 return ret ;
  23.         }
  24.        
  25.         MyService::MyService()
  26.         {
  27.                 if(DEBUG) ALOGD("MyService create\n");
  28.                 pthread_key_create(&sigbuskey,NULL);
  29.                
  30.         }
  31.         MyService::~MyService()
  32.         {
  33.                 pthread_key_delete(sigbuskey);
  34.                 if(DEBUG) ALOGD("MyService destory\n");
  35.         }
  36.         status_t MyService::onTransact(uint32_t code , const Parcel & data,Parcel * reply,uint32_t flags)
  37.         {
  38.                 if(DEBUG) ALOGD("transact for %u\n",code);
  39.                 switch(code)
  40.                 {
  41.                 case 0 :
  42.                         {
  43.                                 reply->writeCString("Greeting from MyService .");
  44.                                 return NO_ERROR ;
  45.                         }
  46.                 default :
  47.                         return BBinder::onTransact(code,data,reply,flags);
  48.                 }
  49.         }
  50. }
复制代码

这里能看到如何消息code是0是我们返回一个"Greeting from MyService ."字符串。

二、然后,我们把MyService加入到Android系统的ServiceManager。这个工作在MyDeamon程序中调用MyService::Instance()来完成,并加入到线程池中成为守护精灵。
  1. #include "MyService.h"
  2. #include <binder/IPCThreadState.h>
  3. #include <binder/ProcessState.h>
  4. #include <binder/IServiceManager.h>

  5. using namespace android;

  6. int main(int argc , char ** argv)
  7. {
  8.         sp<ProcessState> proc(ProcessState::self());
  9.         sp<IServiceManager> sm = defaultServiceManager();
  10.         int ret = MyService::Instance();
  11.         ProcessState::self()->startThreadPool();
  12.         IPCThreadState::self()->joinThreadPool();
  13. }
复制代码

可以看到在MyService::Instance()中的int ret = defaultServiceManager()->addService(String16("tchip.MyService"),new MyService());这一句就是核心。

三、最后,我们在写一个测试程序,从MyService中返回数据。
  1. #include <stdio.h>

  2. #include <binder/IPCThreadState.h>
  3. #include <binder/ProcessState.h>
  4. #include <binder/IServiceManager.h>

  5. using namespace android;

  6. sp<IBinder> binder ;

  7. int main(){
  8.         sp<IServiceManager> sm = defaultServiceManager();
  9.         binder = sm->getService(String16("tchip.MyService"));
  10.         if(binder == 0)
  11.         {
  12.                 printf("MyService not published !\n");
  13.                 return -1 ;
  14.         }
  15.         Parcel data , reply ;
  16.         binder->transact(0,data,&reply);
  17.         const char * msg = reply.readCString();
  18.         printf("msg : %s\n",msg);
  19.         return 0 ;
  20. }
复制代码

我们再写一个Android.mk文件来编译:
  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)

  3. LOCAL_MODULE := MyDeamon

  4. LOCAL_SRC_FILES := \
  5.         MyService.cpp \
  6.         MyDeamon.cpp \
  7.        
  8. LOCAL_SHARED_LIBRARIES := libutils libbinder liblog
  9. LOCAL_MODULE_TAGS := $(TARGET_BUILD_VARIANT)

  10. include $(BUILD_EXECUTABLE)

  11. ######################
  12. # only for test
  13. ######################
  14. include $(CLEAR_VARS)

  15. LOCAL_MODULE := MyTest

  16. LOCAL_SRC_FILES := \
  17.         MyTest.cpp \
  18.        
  19. LOCAL_SHARED_LIBRARIES := libutils libbinder
  20. LOCAL_MODULE_TAGS := optional

  21. include $(BUILD_EXECUTABLE)
复制代码

编译完后把可执行文件push到设备的/system/bin下运行:
先运行MyDeamon,打开服务。
接着在另一个终端运行MyTest


最后的最后,如果我们把这个Native服务放到init.rc中赋予root权限,这样这个服务就可以做更多事情了:
  1. # service MyDeamon
  2. /system/bin/MyDeamon
  3.     class core
  4.     user root
复制代码


作者: bunchen    时间: 2014-10-21 10:19
第一次发帖不知怎样贴图片现在补会运行后的效果图。:(
运行MyTest的结过


Logcat



作者: bunchen    时间: 2014-10-21 10:35
init.rc中这样定义service才对,之前代码贴错了。:'(
  1. # service MyDeamon
  2. service MyDeamon /system/bin/MyDeamon
  3.     class core
  4.     user root
复制代码

作者: xiaofei    时间: 2016-7-8 16:27

谢谢分享




欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/) Powered by Discuz! X3.1