您的位置:首页 > 移动开发 > Android开发

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

部分截图











内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: