android native Service(C++實現service)
阿新 • • 發佈:2019-02-02
服務端
上篇部落格介紹瞭如何用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();
}
}
}