Android Add a native Service

Source: Internet
Author: User

Native service is actually a Linux daemon, providing some services, but since the Android interprocess communication uses the binder mechanism, then we need to follow the Android rules to implement our Native service.

The client uses a proxy class with the same interface when requesting service services. Native service This specifically implements this interface, so Android provides the IInterface class, which is "base class for Binder interfaces", so our Izxtask class inherits it:

public IInterface {public:    enum { TASK_GET_PID = IBinder::FIRST_CALL_TRANSACTION,    };    virtualint0;    DECLARE_META_INTERFACE(ZxTask);};
IMPLEMENT_META_INTERFACE"android.hardware.IZxTask");

Must start with I, because there will be some macros, such as Declare_meta_interface,i start is written to the inside of the macro, so we just passed the zxtask on the line. Our native service provides an interface that is the process number that returns the service.
Below we need to start the differentiation implementation, one is the client, one is the native service.
First look at the proxy class

class Bpzxtask: PublicBpinterface<Izxtask> {public:Bpzxtask(const sp<ibinder>& binder):Bpinterface<Izxtask>(binder){} virtual int getpid(){Parceldata, reply; Data.writeinterfacetoken(izxtask::getinterfacedescriptor()); Remote()->transact(task_get_pid, data, &reply); Return Reply.readint32(); }};

Bpinterface template class, where p is the meaning of the agent. It is the template parameter with the interface we defined earlier.
Bpinterface declares as follows:

publicpublic BpRefBase{public:                                BpInterface(const sp<IBinder>& remote);protected:    virtual IBinder*            onAsBinder();};

Our bpzxtask need to implement the interface functions in the interface classes we define. In the implementation, we are the client, we need to apply to the native service, we use remote to obtain the associated service IBinder object, and then through Transact commit, through reply to obtain the return value.

Let's look at the implementation of Bninterface.

public BnInterface<IZxTask> {public:    virtualonTransactconst0);};
status_t Bnzxtask:: Ontransact (uint32_t code, constParcel& data, Parcel* reply, uint32_t flags){switch (code) { Case Task_get_pid: {Check_interface(Izxtask, Data, reply);int32_t pid = Getpid ();        Reply->writeint32 (PID); ReturnNo_error; } break; default:ReturnBbinder:: Ontransact (Code, Data, reply, flags);}}

Our Transact call in Bpinterface will callback Bninterface's ontransact to handle, we make the request distinction according to the code parameter.

The Bninterface class template is declared as follows:

publicpublic BBinder{public:    virtual sp<IInterface>              queryLocalInterface(const String16& _descriptor);    virtualconst String16&     const;protected:    virtual IBinder*            onAsBinder();};

One of its parent classes is an interface class that inherits from IInterface, and one that represents the Bbinder class on the binder service side.

Below to implement the native service.

publicpublic BnZxTask {public:    virtualintgetPid();    staticcharconstreturn"ZxTask"; }    friend class BinderService<ZxTaskService>;};int ZxTaskService::getPid(){    return getpid();}

Here we implement the Getpid interface provided by the service to implement a logical encapsulation of the Ok,binderservice template for us to start a service.
The Binderservice is implemented as follows:

Template<typename Service>class binderservice{ Public:Staticstatus_tPublish(BOOLallowisolated =false) {sp<iservicemanager> sm (Defaultservicemanager ());returnSm->addservice (String16 (Service::getservicename ()),NewSERVICE (), allowisolated); }Static voidPublishandjointhreadpool (BOOLallowisolated =false) {publish (allowisolated);    Jointhreadpool (); }Static voidInstantiate () {Publish ();}Staticstatus_t shutdown () {returnNo_error; }Private:Static void Jointhreadpool() {sp<processstate> PS (processstate::self ());        Ps->startthreadpool ();        Ps->givethreadpoolname ();    Ipcthreadstate::self ()->jointhreadpool (); }};

It requires a template parameter implementation getServiceName method, publish and the publishAndJoinThreadPool function implements the logic that the service adds to the SM, publish just add, and publishAndJoinThreadPool the service is started.

Here we have completed the development of the native service, which we have compiled into a library.
Android.mk

Local_path:=$(Call My-dir)include $(Clear_vars)Local_src_files :=Zxtask. cppZxtaskservice. cppLocal_c_includes := System/core/includeframeworks/native/includelocal_shared_libraries := Libbinder LibutilsLocal_module:= Libzxtaskinclude $(build_shared_library)

We write a service executable program.
Main.cpp

#include"service/ZxTaskService.h"int main(){    /* code */    android::ZxTaskService::publishAndJoinThreadPool();    return0;}

Android.mk

LOCAL_PATH$(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES :=                                 LOCAL_C_INCLUDES := frameworks/base/zxTaskLOCAL_MODULE:= zxtaskserviceLOCAL_SHARED_LIBRARIES := libzxtask libutils libbinderinclude $(BUILD_EXECUTABLE)

Write a test client

Main.cpp

#include "service/zxtask.h"#include <binder/IServiceManager.h>#include <unistd.h>#include <stdio.h>intMain () {using namespaceAndroid sp<iservicemanager> SM =defaultservicemanager ();printf("%s\n","Get ServiceManager"); Sp<ibinder> Binder =sm->getservice (String16 ("Zxtask")); Sp<izxtask> mtask =interface_cast<izxtask> (binder);printf("Zxtask Service pid%d, client pid:%d", Mtask->getpid (), Getpid ());return 0;}

Android.mk

LOCAL_PATH$(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES :=                                 LOCAL_C_INCLUDES := frameworks/base/zxTaskLOCAL_MODULE:= zxtaskclientLOCAL_SHARED_LIBRARIES := libzxtask libutils libbinderinclude $(BUILD_EXECUTABLE)

It was used interface_cast .

template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){    return INTERFACE::asInterface(obj);}

It uses the Asinterface function, and this function is what we use to declare in Izxtask DECLARE_META_INTERFACE .

# 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 ();   

It declares a description of the class property that we use for the asInterface function.
Look at the IMPLEMENT_META_INTERFACE macro.

#define IMPLEMENT_META_INTERFACE (INTERFACE, NAME) \    ConstAndroid::string16 I# #INTERFACE::d escriptor (NAME); \    Constandroid::string16& I# #INTERFACE:: Getinterfacedescriptor () const {\        returnI# #INTERFACE::d escriptor; \} android::sp<i# #INTERFACE > i# #INTERFACE:: Asinterface (\            Constandroid::sp<android::ibinder>& obj) { Android::sp<i# #INTERFACE > intr; \        if(obj = NULL) {intr =static_cast<i# #INTERFACE *> (\Obj->querylocalinterface (I# #INTERFACE::d escriptor). get ()); \            if(Intr = = NULL) {intr =NewBp# #INTERFACE (obj); \}                                                          }returnIntr } I# #INTERFACE:: i# #INTERFACE () {} \I# #INTERFACE:: ~i# #INTERFACE () {} \

The main view asInterface of the implementation. It calls IBinder's querylocalinterface to query our interface object, where the base class pointer is used, if not new. Our bpzxtask is only used in this function, which is why when I implement it, I'm instructed to put it all in the CPP file.

new Bp##INTERFACE(obj); 

This sentence indicates that our proxy class must start with BP and IBinder object as the parameter of construction, and implement the binding of proxy and IBinder object.

  sp<IBinder> binder =sm->getService(String16("ZxTask"));  

The IBinder object for the service is obtained from the service name, using the interface_cast binding that implements the client's proxy and the service's IBinder, and then we can invoke the Transact function of ibinder in Getpid. This and the remote communication, callback to the native service Ontransact interface, and then processed to return the results, so that the client and service to achieve the communication.

Run as:

code example: Https://git.oschina.net/zhouX/servicedemo.git

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Android Add a native Service

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.