1. 准备工作
(1)因为要调用Android源代码的framework/base里的一些类,所以要确保有android相关源代码
(2)需要交叉编译器, 链接器等工具, 这个可以使用anroid源码里提供的工具,也可以使用单独下载的android ndk
(3)可选: 如果在模拟器(AVD)上运行和调试, 还需要有编译好或者单独下载的android sdk及相应的组件等等, 关于各种组件需求,见
这里用的环境是android源码+单独下载的SDK(包括sdk toos, sdk platform tools和platform组件)
2. 在android源码主目录/development子目录下建立工程目录, 我们的各个模块的代码都将放在这个目录的子目录下
cd ~/android/development
mkdir zp_module
3. 建立service目录,里面放要做的native service源码
ZPService.h
- #ifndef ANDROID_ZPSERVICE_H
- #define ANDROID_ZPSERVICE_H
- #include <utils/RefBase.h>
- #include <binder/IInterface.h>
- #include <binder/Parcel.h>
- namespace android
- {
- class ZPService : public BBinder
- {
- private:
- //mutable Mutex m_Lock;
- //int32_t m_NextConnId;
- public:
- static int Instance();
- ZPService();
- virtual ~ZPService();
- virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
- };
- }
- #endif
ZPService.cpp
- #include <binder/IServiceManager.h>
- #include <binder/IPCThreadState.h>
- #include "ZPService.h"
- namespace android
- {
- //static struct sigaction oldact;
- static pthread_key_t sigbuskey;
-
- int ZPService::Instance()
- {
- LOGE("ZPService Instantiate\n");
- int ret = defaultServiceManager()->addService(
- String16("zp.svc"), new ZPService());
- LOGE("ZPService ret = %d\n", ret);
- return ret;
- }
- ZPService::ZPService()
- {
- LOGV("ZPService create\n");
- //m_NextConnId = 1;
- pthread_key_create(&sigbuskey,NULL);
- }
- ZPService::~ZPService()
- {
- pthread_key_delete(sigbuskey);
- LOGV("ZPService destory\n");
- }
- status_t ZPService::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 += 1000;
- reply->writeInt32(num);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
- }
- }
Android.mk
- LOCAL_PATH:=$(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:=ZPService.cpp
- LOCAL_SHARED_LIBRARIES:=libutils libbinder
- LOCAL_MODULE_TAGS:=optional
- LOCAL_MODULE:=libZPService
- LOCAL_PRELINK_MODULE:=false
- include $(BUILD_SHARED_LIBRARY)
4. 建立svcserver目录,放置server源代码, 它主要用来将我们的service注册到系统.
zpserver.cpp
- #include <stdio.h>
- #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 "../service/ZPService.h"
- using namespace android;
- int main(int arg, char** argv)
- {
- printf("server - ain() begin\n");
- sp<ProcessState> proc(ProcessState::self());
- sp<IServiceManager> sm = defaultServiceManager();
- //LOGI("ServiceManager: %p\n", sm.get());
- printf("server - erviceManager: %p\n", sm.get());
- int ret = ZPService::Instance();
- printf("server - ZPService::Instance return %d\n", ret);
- ProcessState::self()->startThreadPool();
Android.mk
- LOCAL_PATH:=$(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:=zpserver.cpp
- LOCAL_SHARED_LIBRARIES:=libutils libbinder libZPService
- LOCAL_MODULE_TAGS:=optional
- LOCAL_MODULE:=zpserver
- include $(BUILD_EXECUTABLE)
5. 创建svcclient目录, 放置client源代码,它用于调用service提供的服务. 它编译成一个动态库,供其他可执行程序调用, 也可以直接将它和第6步的调用程序直接编译成一个可执行文件
ZPClient.h
- #ifndef ANDROID_ZPCLIENT_H
- #define ANDROID_ZPCLIENT_H
- namespace android
- {
- class ZPClient
- {
- public:
- int setN(int n);
- private:
- static void getZPService();
- };
- }
- #endif
ZPClient.cpp
- #include <binder/IServiceManager.h>
- #include <binder/IPCThreadState.h>
- #include "ZPClient.h"
- namespace android
- {
- sp<IBinder> binder;
-
- int ZPClient::setN(int n)
- {
- getZPService();
- Parcel data, reply;
- data.writeInt32(getpid());
- data.writeInt32(n);
-
- LOGE("client - binder->transact()\n");
- binder->transact(0, data, &reply);
- int r = reply.readInt32();
- return r;
- }
- void ZPClient::getZPService()
- {
- sp<IServiceManager> sm = defaultServiceManager();
- binder = sm->getService(String16("zp.svc"));
- LOGE("client - etService: %p\n", sm.get());
- if(binder == 0)
- {
- LOGW("ZPService not published, waiting...");
- return;
- }
- }
- }
Android.mk
- LOCAL_PATH:=$(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:=ZPClient.cpp
- LOCAL_SHARED_LIBRARIES:=libutils libbinder
- LOCAL_MODULE_TAGS:=optional
- LOCAL_MODULE:=libZPClient
- LOCAL_PRELINK_MODULE:=false
- include $(BUILD_SHARED_LIBRARY)
6. 创建svctest目录, 在里面开发一个测试程序,调用第5步的client库提供的接口,访问我们的service
test.cpp
- #include <stdio.h>
- #include "../svcclient/ZPClient.h"
- using namespace android;
- int main(int argc, char** argv)
- {
- ZPClient client;
- int ret = client.setN(2012);
- printf("setN return: %d\n", ret);
- return 0;
- }
Android.mk
- LOCAL_PATH:=$(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:=test.cpp
- LOCAL_SHARED_LIBRARIES:=libZPClient
- LOCAL_MODULE_TAGS:=optional
- LOCAL_MODULE:=svctest
- include $(BUILD_EXECUTABLE)
完成以上几步后, 我们的工程的目录结构如下(zp_module的父目录是development):
- zp_module/
- |-- Android.mk
- |-- service
- | |-- Android.mk
- | |-- ZPService.cpp
- | `-- ZPService.h
- |-- svcclient
- | |-- Android.mk
- | |-- ZPClient.cpp
- | `-- ZPClient.h
- |-- svcserver
- | |-- Android.mk
- | `-- zpserver.cpp
- `-- svctest
- |-- Android.mk
- `-- test.cpp
7. 编译所有项目
第一种方法, 进入android源码主目录,运行
source build/envsetup.sh 或 . build/envsetup.sh
然后进入development下你的源代码的各个子目录, 根据信赖性先后依次编译各个项目,比如进入development/zp_module/service, 运行 mm
第二种方法, 在zp_module下创建一个Android.mk文件, 输入以下内容:
- include $(call all-subdir-makefiles
然后直接在zp_module目录下运行mm
8. 在模拟器里调试编译好的东西
(1) 打开emulator
emulator -avd avd4.0.3 -scale 0.6 -partition-size 256
(2) 打开adb, 等avd就绪后(用adb get-state查看状态,为device即准备好), 将编译好的库和可执行程序送入模拟器
- zp@zp-desktop:~$ adb remount
- remount succeeded
- zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPService.so /system/lib
- 210 KB/s (10216 bytes in 0.047s)
- zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPClient.so /system/lib
- 122 KB/s (5516 bytes in 0.044s)
- zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/zpserver /data
- 124 KB/s (5572 bytes in 0.043s)
- zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/svctest /data
- 121 KB/s (5568 bytes in 0.044s)
(3) 进入模拟器shell,先后运行zpserver和svctest
- zp@zp-desktop:~$ adb shell
- # /data/zpserver
- server - ain() begin
- server - erviceManager: 0xaa88
- server - ZPService::Instance return 0
- zp@zp-desktop:~$ adb shell
- # /data/svctest
- setN return: 3012
- #
证明一切正确.
转自:http://blog.csdn.net/blackboyofsnp/article/details/7243070
阅读(7222) | 评论(0) | 转发(0) |