android native Service(C++实现service)

2 篇文章 0 订阅
1 篇文章 0 订阅

服务端

上篇博客介绍了如何用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();
        }

    }

}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android中,可以使用AIDL(Android Interface Definition Language)来定义跨进程通信的接口。如果要让Java客户端调用本地实现的AIDL服务,可以使用JNI来实现。以下是实现步骤: 1.编写本地服务代码:使用C或C++编写本地服务的代码,并将其编译成本地库,例如.dll文件(Windows平台)或.so文件(Linux平台)。 2.编写AIDL接口:在Android中,使用AIDL定义接口。你需要编写一个AIDL文件来定义服务的接口。 3.编写Java代码:在Java中编写客户端代码,并使用JNI调用本地库。你需要将AIDL接口转换为Java接口,并使用JNI调用本地实现。 4.将本地库加载到Java中:使用System.loadLibrary()方法将本地库加载到Java中。 5.连接到服务:在Java代码中连接到AIDL服务。 以下是一个简单的示例代码: C/C++本地服务代码: ```c #include <jni.h> JNIEXPORT jstring JNICALL Java_com_example_MyService_nativeMethod(JNIEnv *env, jobject obj) { return (*env)->NewStringUTF(env, "Hello from native method!"); } ``` AIDL接口: ```aidl interface IMyService { String sayHello(); } ``` Java客户端代码: ```java public class MyService extends Service { // 定义本地方法 private native String nativeMethod(); // 实现AIDL接口 private final IMyService.Stub mBinder = new IMyService.Stub() { @Override public String sayHello() throws RemoteException { return nativeMethod(); // 调用本地方法 } }; @Override public IBinder onBind(Intent intent) { return mBinder; // 返回AIDL接口 } static { System.loadLibrary("mylib"); // 加载本地库 } } ``` 注意:这只是一个简单的示例,实际情况可能更加复杂。你需要仔细阅读JNI和AIDL文档,并且确保你的本地代码和Java代码之间的交互是正确的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值