Android通过编译源代码提供系统服务-android学习之旅(85)
2015-11-10 21:20
239 查看
通过编译android4.1.2的源代码,添加一个FregServer的系统服务,以及一个服务代理FregClient
具体分为三部分,client,common,server,common中规定了client和common的接口,和一些公共方法
client部分代码
#define LOG_TAG "FregTest" #include <utils/Log.h> #include <binder/IServiceManager.h> #include "../common/IFregService.h" int main() { IServiceManager = defaultServiceManager(); sp<IBinder> binder = defaultServiceManager()->getService(String16(FREG_SERVICE)); //通过servicemanager获取名为xxx的Service的BpBinder代理对象 if(binder == NULL) { ALOGE("[C] Failed to get freg service: %s.\n", FREG_SERVICE); return -1; } ALOGE("[C] Got BpBinder"); sp<IFregService> service = IFregService::asInterface(binder); //将bpbinder代理对象封装为bpfregservice对象 if(service == NULL) { ALOGE("[C] Failed to get freg service interface.\n"); return -2; } ALOGE("[C] Got BpFregService"); ALOGE("[C] Reading original value from FregService.\n"); int32_t val = service->getVal(); ALOGE("[C] Result: %d.\n", val); sleep(15); ALOGE("[C] Add value 1 to FregService.\n"); val += 1; service->setVal(val); ALOGE("[C] Reading the value from FregService again:\n"); val = service->getVal(); ALOGE("[C] Result: %d.\n", val); return 0; }
mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := ../common/IFregService.cpp \ FregClient.cpp LOCAL_SHARED_LIBRARIES:= libcutils libutils libbinder LOCAL_MODULE := FregClient include $(BUILD_EXECUTABLE)
Server部分
#define LOG_TAG "FregTest" #include <stdlib.h> #include <fcntl.h> #include <utils/Log.h> #include <binder/IServiceManager.h> #include <binder/IPCThreadState.h> #include "../common/IFregService.h" #define FREG_DEVICE_NAME "/dev/freg" class FregService : public BnFregService { public: FregService() { val = 0; ALOGE("[S] Tread: %d. In FregService().", gettid()); } virtual ~FregService() { ALOGE("[S] Tread: %d. In ~FregService().", gettid()); } public: static void instantiate() { defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService()); //获取servicemanager并调用addService函数实现服务注册 ALOGE("[S] Tread: %d. instantiate(), addService-%s", gettid(), FREG_SERVICE); } int32_t getVal() { ALOGE("[S] Tread: %d. In getVal(), val-%d returned.", gettid(), val); return val; } void setVal(int32_t v) { val = v; ALOGE("[S] Tread: %d. In setVal(), val-%d set.", gettid(), val); } private: int val; }; int main(int argc, char** argv) { FregService::instantiate(); ProcessState::self()->startThreadPool(); //启动线程池 ALOGE("[S] Tread: %d. ProcessState::self()->startThreadPool() finished.", gettid()); IPCThreadState::self()->joinThreadPool(); //将主线程加入线程池 ALOGE("[S] Tread: %d. IPCThreadState::self()->joinThreadPool(); finished.", gettid()); return 0; }
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := ../common/IFregService.cpp \ FregServer.cpp LOCAL_SHARED_LIBRARIES:= libcutils libutils libbinder LOCAL_MODULE := FregServer include $(BUILD_EXECUTABLE)
common部分
#define LOG_TAG "IFregService" #include <utils/Log.h> #include "IFregService.h" using namespace android; enum { GET_VAL = IBinder::FIRST_CALL_TRANSACTION, SET_VAL }; class BpFregService: public BpInterface<IFregService> //通信请求的发送 { public: BpFregService(const sp<IBinder>& impl) : BpInterface<IFregService>(impl) { } public: int32_t getVal() { Parcel data; data.writeInterfaceToken(IFregService::getInterfaceDescriptor()); //获取了Ifregservice的接口名,并调用了parcel.writeInterfaceToken函数写入了data中 Parcel reply; remote()->transact(GET_VAL, data, &reply); //remote获取bpbinder代理对象,通过transact函数来发送请求 int32_t val = reply.readInt32(); return val; } void setVal(int32_t val) { Parcel data; data.writeInterfaceToken(IFregService::getInterfaceDescriptor()); data.writeInt32(val); Parcel reply; remote()->transact(SET_VAL, data, &reply); } }; IMPLEMENT_META_INTERFACE(FregService, "hikame.IFregService");//见最下 status_t BnFregService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) //通信数据的接收与处理 { switch(code) { case GET_VAL: { CHECK_INTERFACE(IFregService, data, reply); int32_t val = getVal(); reply->writeInt32(val); return NO_ERROR; } case SET_VAL: { CHECK_INTERFACE(IFregService, data, reply); int32_t val = data.readInt32(); setVal(val); return NO_ERROR; } default: { return BBinder::onTransact(code, data, reply, flags); } } } /*IFregService的具体实现 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const android::String16 I##INTERFACE::descriptor(NAME); \ const android::String16& \ I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ const android::sp<android::IBinder>& obj) \ { \ android::sp<I##INTERFACE> intr; \ if (obj != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ I##INTERFACE::descriptor).get()); \ if (intr == NULL) { \ intr = new Bp##INTERFACE(obj); \ } \ } \ return intr; \ } \ I##INTERFACE::I##INTERFACE() { } \ I##INTERFACE::~I##INTERFACE() { } \ */
#ifndef IFREGSERVICE_H_ #define IFREGSERVICE_H_ #include <utils/RefBase.h> #include <binder/IInterface.h> #include <binder/Parcel.h> #define FREG_SERVICE "hikame.FregService" //Service名称 using namespace android; //在各个头文件中namespace为android的代码部分都被使用了 class IFregService: public IInterface { public: /* #define DECLARE_META_INTERFACE(INTERFACE) \ static const android::String16 descriptor; \ static android::sp<I##INTERFACE> asInterface( \ const android::sp<android::IBinder>& obj); \ virtual const android::String16& getInterfaceDescriptor() const; \ I##INTERFACE(); \ virtual ~I##INTERFACE(); \ 定义了构造函数和析构函数,descriptor是接口名,getInterfaceDescriptor是获取该接口名的函数 ??这个android::sp是什么?A:/include/utils/StrongPointer.h */ DECLARE_META_INTERFACE(FregService); virtual int32_t getVal() = 0; virtual void setVal(int32_t val) = 0; }; class BnFregService: public BnInterface<IFregService> { public: virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; #endif
好了放他们放到android-4.1.2_r1-JZO54K\external\binder目录下, external目录下可以放这些外来的服务
执行编译命令
1.通过xShell连接到远程的ubuntu服务器,里面下载了Android源代码
2.cd 到相应版本源代码的根目录
3.执行source build/envsetup.sh初始化环境
4.执行mmm ./external/binder/server/
5.执行mmm ./external/binder/client/ ,分别编译两个模块
6然后在out/target/product/gerneric/system/bin目录底下,查看相应的生成文件
下一步是把相应的服务文件拷贝到手机的/data/local/tmp目录下
1.代开adb shell,执行su,进入root模式
2.在服务文件的目录,按住shift右键,打开命令窗口
3.输入adb push FregServer /data/local/tmp,adb push FregClient /data/local/tmp,拷贝到相应的目录
4.su进入root模式,进入 /data/local/tmp目录,执行./FregClient
5.查看日志adb logcat FregTest:i *:s
部分截图
相关文章推荐
- Android学习之随笔(一)
- Android-内存优化之OOM
- eclipise Android 开发d环境搭建
- SparseArray
- android SQLite实现本地登录注册功能,SQLite简单应用(android studio)
- Android兼容性问题 -- FrameLayout中View设置margin无效
- [原创] Android 自定义AlertDialog 去黑边终极解决方案(亲测有效!)
- [Android] ImageView.ScaleType设置图解
- Android开发过程中内存泄露检测
- android:json解析库的选择
- ubuntu创建wifi热点(android可识别)
- Android studio安装配置常见问题及其解决方案
- Android 中的dp,px,pt,sp比较
- android sqllite数据库使用详解
- Android启动过程深入解析
- 电容屏/电阻屏Android虚拟按键实现的两种方法
- Android的消息机制
- Android签名INSTALL_PARSE_FAILED_NO_CERTIFICATES问题
- Android中服务端代码如何导入工程当中
- Android点击EditText文本框之外任何地方隐藏键盘的解决办法