一个Native Service的完整示例

  • 格式:docx
  • 大小:25.82 KB
  • 文档页数:8

一个Native Service的完整示例1. 准备工作(1)因为要调用Android源代码的framework/base里的一些类,所以要确保有android相关源代码(2)需要交叉编译器, 链接器等工具, 这个可以使用anroid源码里提供的工具,也可以使用单独下载的android ndk(3)可选: 如果在模拟器(AVD)上运行和调试, 还需要有编译好或者单独下载的android sdk及相应的组件等等, 关于各种组件需求,见/sdk/installing.html#components提到的"Recommended Components", 确保满足"Basic"需求这里用的环境是android源码+单独下载的SDK(包括sdktoos, sdk platform tools和platform组件)2. 在android源码主目录/development子目录下建立工程目录, 我们的各个模块的代码都将放在这个目录的子目录下cd ~/android/developmentmkdirzp_module3. 建立service目录,里面放要做的native service源码ZPService.h1.#ifndef ANDROID_ZPSERVICE_H2.#define ANDROID_ZPSERVICE_H3.4.#include <utils/RefBase.h>5.#include <binder/IInterface.h>6.#include <binder/Parcel.h>7.space android9.{10.class ZPService :public BBinder11.{12.private:13.//mutable Mutexm_Lock;14.//int32_t m_NextConnId;15.16.public:17. static int Instance();18. ZPService();19. virtual ~ZPService();20. virtual status_tonTransact(uint32_t,const Parcel&, Parcel*, uint32_t);21.};22.}23.24.#endifZPService.cpp1.#include <binder/IServiceManager.h>2.#include <binder/IPCThreadState.h>3.#include "ZPService.h"4.space android6.{7.//static structsigactionoldact;8. static pthread_key_tsigbuskey;9.10.int ZPService::Instance()11.{12. LOGE("ZPService Instantiate\n");13.int ret = defaultServiceManager()->addService(14. String16("zp.svc"), new ZPService());15. LOGE("ZPService ret = %d\n", ret);16. return ret;17.}18.19. ZPService::ZPService()20.{21. LOGV("ZPService create\n");22.//m_NextConnId = 1;23. pthread_key_create(&sigbuskey,NULL);24.}25.26. ZPService::~ZPService()27.{28. pthread_key_delete(sigbuskey);29. LOGV("ZPServicedestory\n");30.}31.32. status_tZPService::onTransact(uint32_t code,33.const Parcel& data,34. Parcel* reply,35. uint32_t flags)36.{37. switch(code)38.{39.case 0:40.{41. pid_tpid = data.readInt32();42.int num = data.readInt32();43. num += 1000;44. reply->writeInt32(num);45. return NO_ERROR;46.} break;47. default:48. return BBinder::onTransact(code, data, reply, flags);49.}50.}51.}Android.mk1.LOCAL_PATH:=$(call my-dir)2.include $(CLEAR_VARS)3.LOCAL_SRC_FILES:=ZPService.cpp4.LOCAL_SHARED_LIBRARIES:=libutilslibbinder5.LOCAL_MODULE_TAGS:=optional6.LOCAL_MODULE:=libZPService7.LOCAL_PRELINK_MODULE:=false8.include $(BUILD_SHARED_LIBRARY)4. 建立svcserver目录,放置server源代码, 它主要用来将我们的service注册到系统.zpserver.cpp1.#include <stdio.h>2.#include <sys/types.h>3.#include <unistd.h>4.#include <grp.h>5.#include <binder/IPCThreadState.h>6.#include <binder/ProcessState.h>7.#include <binder/IServiceManager.h>8.#include <utils/Log.h>9.#include "../service/ZPService.h"10.ing namespace android;12.13.14.int main(int arg, char** argv)15.{16. printf("server - ain() begin\n");17. sp<ProcessState> proc(ProcessState::self());18. sp<IServiceManager> sm = defaultServiceManager();19.//LOGI("ServiceManager: %p\n", sm.get());20. printf("server - erviceManager: %p\n", sm.get());21.int ret = ZPService::Instance();22. printf("server - ZPService::Instance return %d\n", ret);23. ProcessState::self()->startThreadPool();Android.mk1.LOCAL_PATH:=$(call my-dir)2.include $(CLEAR_VARS)3.LOCAL_SRC_FILES:=zpserver.cpp4.LOCAL_SHARED_LIBRARIES:=libutilslibbinderlibZPService5.LOCAL_MODULE_TAGS:=optional6.LOCAL_MODULE:=zpserver7.include $(BUILD_EXECUTABLE)5. 创建svcclient目录, 放置client源代码,它用于调用service提供的服务. 它编译成一个动态库,供其他可执行程序调用, 也可以直接将它和第6步的调用程序直接编译成一个可执行文件ZPClient.h1.#ifndef ANDROID_ZPCLIENT_H2.#define ANDROID_ZPCLIENT_H3.space android5.{6.class ZPClient7.{8.public:9.int setN(int n);10.private:11. static void getZPService();12.};13.}14.15.#endifZPClient.cpp点击(此处)折叠或打开1.#include <binder/IServiceManager.h>2.#include <binder/IPCThreadState.h>3.#include "ZPClient.h"4.5.space android7.{8. sp<IBinder> binder;9.10.int ZPClient::setN(int n)11.{12. getZPService();13. Parcel data, reply;14. data.writeInt32(getpid());15. data.writeInt32(n);16.17. LOGE("client - binder->transact()\n");18. binder->transact(0, data,&reply);19.int r = reply.readInt32();20. return r;21.}22.23. void ZPClient::getZPService()24.{25. sp<IServiceManager> sm = defaultServiceManager();26. binder = sm->getService(String16("zp.svc"));27. LOGE("client - etService: %p\n", sm.get());28.if(binder == 0)29.{30. LOGW("ZPService not published, waiting...");31. return;32.}33.}34.35.}Android.mk1.LOCAL_PATH:=$(call my-dir)2.include $(CLEAR_VARS)3.LOCAL_SRC_FILES:=ZPClient.cpp4.LOCAL_SHARED_LIBRARIES:=libutilslibbinder5.LOCAL_MODULE_TAGS:=optional6.LOCAL_MODULE:=libZPClient7.LOCAL_PRELINK_MODULE:=false8.include $(BUILD_SHARED_LIBRARY)6. 创建svctest目录, 在里面开发一个测试程序,调用第5步的client库提供的接口,访问我们的servicetest.cpp1.#include <stdio.h>2.#include "../svcclient/ZPClient.h"3.ing namespace android;5.6.int main(int argc, char** argv)7.{8. ZPClient client;9.int ret = client.setN(2012);10. printf("setN return: %d\n", ret);11. return 0;12.}Android.mk1.LOCAL_PATH:=$(call my-dir)2.include $(CLEAR_VARS)3.LOCAL_SRC_FILES:=test.cpp4.LOCAL_SHARED_LIBRARIES:=libZPClient5.LOCAL_MODULE_TAGS:=optional6.LOCAL_MODULE:=svctest7.include $(BUILD_EXECUTABLE)完成以上几步后,我们的工程的目录结构如下(zp_module的父目录是development):点击(此处)折叠或打开1.zp_module/2.|-- Android.mk3.|-- service4.||-- Android.mk5.||-- ZPService.cpp6.| `-- ZPService.h7.|-- svcclient8.||-- Android.mk9.||-- ZPClient.cpp10.| `-- ZPClient.h11.|-- svcserver12.||-- Android.mk13.| `-- zpserver.cpp14.`-- svctest15.|-- Android.mk16. `-- test.cpp7. 编译所有项目第一种方法, 进入android源码主目录,运行source build/envsetup.sh 或 . build/envsetup.sh然后进入development下你的源代码的各个子目录, 根据信赖性先后依次编译各个项目,比如进入development/zp_module/service, 运行 mm第二种方法, 在zp_module下创建一个Android.mk文件, 输入以下内容:1.include $(call all-subdir-makefiles然后直接在zp_module目录下运行mm8. 在模拟器里调试编译好的东西(1) 打开emulatoremulator -avd avd4.0.3 -scale 0.6 -partition-size 256(2) 打开adb, 等avd就绪后(用adb get-state查看状态,为device即准备好),将编译好的库和可执行程序送入模拟器1.zp@zp-desktop:~$ adb remount2.remount succeeded3.zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPService.so /system/lib4.210 KB/s (10216 bytes in 0.047s)5.zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPClient.so /system/lib6.122 KB/s (5516 bytes in 0.044s)7.zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/zpserver /data8.124 KB/s (5572 bytes in 0.043s)9.zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/svctest /data10.121 KB/s (5568 bytes in 0.044s)(3) 进入模拟器shell,先后运行zpserver和svctest1.zp@zp-desktop:~$ adb shell2.# /data/zpserver3.server- ain() begin4.server- erviceManager: 0xaa885.server- ZPService::Instance return 06.zp@zp-desktop:~$ adb shell7.# /data/svctest8.setN return: 30129.#证明一切正确.转自:/blackboyofsnp/article/details/7243070。