1. 程式人生 > >android native Service(C++實現service)

android native Service(C++實現service)

服務端

上篇部落格介紹瞭如何用java實現android Binder服務端,並且實現java和c的客戶端都通過binder與服務端通訊,這篇我們講如何使用C++實現服務端,然後通過java和c的客戶端與之通訊。

main.cpp

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <private/android_filesystem_config.h>

#include "nativeService.h"
#define SERVICE_NAME "penguinmipc" using namespace android; int main(int argc, char *argv[]) { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); sm->addService(String16(SERVICE_NAME), new nativeService()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); return
0; }
nativeService.h
#ifndef DAEMON_BBINDER_H
#define DAEMON_BBINDER_H

#include <utils/RefBase.h>
#include <binder/Binder.h>
#include <binder/Parcel.h>
#include <cutils/log.h>

namespace android {
    class nativeService : public BBinder
    {
    public:


        typedef
enum nativeService_transact { TESTIPC = 1 }nativeService_transact_t; nativeService(); virtual ~nativeService(); private: virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); }; }; //namespace android #endif //DAEMON_BBINDER_H
nativeService.cpp
#include <utils/String8.h>

#include "nativeService.h"

namespace android {

    nativeService::nativeService()
    {
        printf("onCreate\n");


    }

    nativeService::~nativeService()
    {
        printf("onDestroy\n");


    }


    status_t nativeService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
        status_t ret = -1;
        printf("onTransact. code:%d, data.dataSize:%d\n", code, data.dataSize());
        char mac[64]={"this is is native service"};
        char sn[128] = {"this is native service 111"};
        switch (code)
        {
        case TESTIPC:
            printf("TESTIPC\n");

            cout<<"yes"<<;
            reply->writeString16(String16(mac));
            ret = 0;


            break;

        case IBinder::INTERFACE_TRANSACTION:
            printf("INTERFACE_TRANSACTION\n");

            reply->writeString16(String16(sn));
            ret = 0;
            break;

        default:
            printf("TRANSACT_CODE_UNKNOWN\n");
            break;
        }

        return ret;
    }
}; //namespace android

Android.mk
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= nativeService

LOCAL_MODULE_TAGS:= optional

LOCAL_SRC_FILES := \
    nativeService.cpp \
    main.cpp

LOCAL_SHARED_LIBRARIES := libcutils libutils libbinder

LOCAL_C_INCLUDES:= $(LOCAL_PATH) \
    frameworks/base/include/

include $(BUILD_EXECUTABLE)

客戶端 c++

client.cpp

#include <binder/Parcel.h>
#include <binder/IServiceManager.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <utils/String8.h>


using namespace android;
static sp<IBinder> mService = NULL;

static bool mInited = false;

static int service_init()
{
    sp<IServiceManager> sm = defaultServiceManager();
        fflush(stdout);
    if(sm == NULL)
    {
        fprintf(stderr, "service: Unable to get default service manager!\n");
        return -1;
    }

    mService = sm->checkService(String16("penguinmipc"));


    if(mService == NULL )
    {
        fprintf(stderr, "can not find  service!\n");
        return -1;
    }

    mInited = true;
    return 0;
}
static int Cpp_testipc(char* value, int size)
{
    if(!mInited){
        printf("service init failed\n");
        return -1;
    }

    Parcel data, reply;

    mService->transact(1, data, &reply);

    String16 s16 = reply.readString16();
    String8 s8 = String8(s16);
    int len = (s8.length() > size)?size:s8.length();
    strncpy(value, s8.string(), len);
    value[len] = '\0';
    return 0;
}

int main(int argc,  char *argv[])
{
    if(service_init() != 0){
        printf("failed 1\n");
        return -1;
    }
    char result[1024] = {0};
    if(Cpp_testipc(result,sizeof(result)) == 0){

        printf("result:%s\n",result);
        return 0;
    }
    return -1;
}

客戶端 java

IPCClient.java
package com.example.ipcclient;


import com.example.ipcservice.IPC;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class IPCClient extends Activity {

    private static final String TAG = "IPCClient";
    private TextView text ;
    IBinder mService = null;
    private IPC mIPC;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.w(TAG,"onCreate");
        setContentView(R.layout.activity_main);
        text = (TextView)findViewById(R.id.text);
        getNativeService();
    }

    public void getNativeService(){
        mService = ServiceManager.getService("penguinmipc");
        if(mService == null){
            Log.w(TAG,"failed get service");
            return ;
        }
        Parcel data = null;
        Parcel reply = null;
        String result = null;
        try {

            {
                data = Parcel.obtain();
                reply = Parcel.obtain();
                if(mService.transact(1,data,reply,0)) {
                    result = reply.readString();
                    Log.d(TAG, "got result: "+result);
                } else {
                    result = null;
                    Log.e(TAG, "Failed to get "+1);
                }
                data.recycle(); data = null;
                reply.recycle(); reply = null;
            }

        }
        catch(Throwable t) {
            Log.e(TAG, "Exception", t);
        }
        if(null != data) {
            data.recycle();
        }
        if(null != reply) {
            reply.recycle();
        }

    }

}