binder 实例集锦

目录

 

binder c 实例

android App 调用binder c 服务实例

java 程序调用binder c


binder c 实例

  • 接口及服务、客户端定义

IMyService.h


#ifndef IMYSERVICE_H
#define IMYSERVICE_H
 
#include "cur_log.h"
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/String16.h>
 
#define MY_SERVICE "Myservice"
#define DESCRIPTOR "com.example.myapplication.IMyService"
 
using namespace android;
namespace android
{
 
// 声明业务接口, Bp Bn 继承 业务接口
    class IMyService : public IInterface
    {
    public:
        // 定义命令字段
        enum
        {
            // SEND_INT = 0 , 可自定义
            SEND_INT = IBinder::FIRST_CALL_TRANSACTION,
            GET_STRING,
            GET_INT,
            SAY_HELLO,
        };
 
        // 使用宏,声明 MyService 业务接口,将业务和通信牢牢地钩在了一起
        DECLARE_META_INTERFACE(MyService);
        // 声明方法
        virtual void sendInt(int32_t val) = 0;
        virtual String8 getString() = 0;
        virtual int32_t getInt() = 0;
        virtual void sayHello() = 0;
 
    };
 
 
// 声明客户端 BpMyService
    class BpMyService : public BpInterface<IMyService>
    {
    public:
        BpMyService(const sp<IBinder>& impl);
        ~BpMyService();
        virtual void sendInt(int32_t val);
        virtual String8 getString();
        virtual int32_t getInt();
        virtual void sayHello();
 
    };
 
 
// 声明服务端 BnMyService
    class BnMyService : public BnInterface<IMyService>
    {
    public:
        // BnXXService实现了onTransact函数,它将根据消息码调用对应的业务逻辑函数
        virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
        BnMyService();
        ~BnMyService();
        virtual void sendInt(int32_t val);
        virtual String8 getString();
        virtual int32_t getInt();
        virtual void sayHello();
 
    private:
        int32_t option;
 
    };
 
 
}
#endif
  • 接口及服务端实现

IMyService.cpp

#include "IMyService.h"
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
 
namespace android
{
    // 实现 IMPLEMENT_META_INTERFACE 宏模板定义 MyService 业务接口, 将业务和通信牢牢地钩在了一起
    IMPLEMENT_META_INTERFACE(MyService, DESCRIPTOR);
 
 
    /***************************************************************************************************
     *   客户端
    */
 
        BpMyService::BpMyService(const sp<IBinder>& impl) : BpInterface<IMyService>(impl)
        {
 
        }
        BpMyService::~BpMyService() {};
        void BpMyService::sendInt(int32_t val)
        {
            Parcel data, reply;
            data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
            data.writeInt32(val);
            remote()->transact(SEND_INT, data, &reply);
        }
 
        String8 BpMyService::getString()
        {
            Parcel data, reply;
            data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
            remote()->transact(GET_STRING, data, &reply);
            String8 res = reply.readString8();
            return res;
        }
 
        int32_t BpMyService::getInt()
        {
            Parcel data, reply;
            data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
            remote()->transact(GET_INT, data, &reply);
            int32_t val = reply.readInt32();
            return val;
        }
        void BpMyService::sayHello()
        {
            Parcel data, reply;
            data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
            remote()->transact(SAY_HELLO, data, &reply);
            int32_t val = reply.readInt32();
            printf("say hello %d \n", val);
 
        }
 
    /***************************************************************************************************
    *  服务端
    */
    BnMyService::BnMyService()
    {
        option = 0;
    }
 
    BnMyService::~BnMyService()
    {}
    /* 接收远程消息,处理 onTransact 方法 */
    status_t BnMyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
        switch(code)
        {
            case SEND_INT:
                {
                    CHECK_INTERFACE(IMyService, data, reply);
                    int32_t val = data.readInt32();  // 调用服务类的函数
                    sendInt(val);
                    return NO_ERROR;
                }
                break;
            case GET_STRING:
                {
                    CHECK_INTERFACE(IMyService, data, reply);
                    String8 res = getString(); // 调用服务类的函数
                    reply->writeString8(res);
                    return NO_ERROR;
                }
                break;
            case GET_INT:
                {
                    CHECK_INTERFACE(IMyService, data, reply);
                    int32_t val = getInt(); // 调用服务类的函数
                    reply->writeInt32(val);
                    return NO_ERROR;
                }
                break;
            case SAY_HELLO:
                {
                    CHECK_INTERFACE(IMyService, data, reply);
                    sayHello();
                    reply->writeInt32(2019);
                    return NO_ERROR;
                }
                break;
            default:
                return BBinder::onTransact(code, data, reply, flags);
        }
 
    }
 
    void BnMyService::sendInt(int32_t val)
    {
        option = val;
    }
 
    int32_t BnMyService::getInt()
    {
        return option;
    }
 
    String8 BnMyService::getString()
    {
        String8 str;
        if(option <= 0)
        {
            str = String8("val <= 0");
        }
        else
        {
            str = String8("val > 0 ");
        }
        return str;
    }
    void BnMyService::sayHello()
    {
        printf("Hello, %s\n", __func__);
    }
 
}



 

  • 服务端实现

MyServer.cpp

#include "IMyService.h"
#include <binder/IServiceManager.h>
 
int main()
{

    sp < IServiceManager > sm = defaultServiceManager(); //获取service manager引用
	//sm 为BpServiceManager

	
	cur_loge("getService start");
    sp < IBinder > binder = sm->getService(String16(MY_SERVICE));//获取名为 "Myservice" 的binder接口
	//这里调用调用BpBinder.transact->IPCThread.transact

	if(binder == NULL)
	{
		cur_loge("error, binder = NULL %s", __func__);
		return -1;
	}
 
    // 获取 client <--> service,binder 为BpBinder 对,service为BpMyService 对象

	sp<IMyService> service = IMyService::asInterface(binder);

	if(service == NULL)
	{
		cur_loge("error, service = NULL %s", __func__);
	}
	
	for(int32_t i = 0; i < 10; i++)
	{
		service->sendInt(-i);
		String8 str1 = service->getString();
		cur_logi("val = %d, str1 : %s", service->getInt(), str1.string());
 
		service->sendInt(i);
		String8 str2 = service->getString();
	    cur_logi("val = %d, str2 : %s", service->getInt(), str2.string());
	}
    service->sayHello();
	return 0;
}

 

  • 客户端实现

MyClient.cpp

#include "IMyService.h"
#include <binder/IServiceManager.h>
 
int main()
{

    sp < IServiceManager > sm = defaultServiceManager(); //获取service manager引用
	//sm 为BpServiceManager

	
	cur_loge("getService start");
    sp < IBinder > binder = sm->getService(String16(MY_SERVICE));//获取名为 "Myservice" 的binder接口
	//这里调用调用BpBinder.transact->IPCThread.transact

	if(binder == NULL)
	{
		cur_loge("error, binder = NULL %s", __func__);
		return -1;
	}
 
    // 获取 client <--> service,binder 为BpBinder 对,service为BpMyService 对象

	sp<IMyService> service = IMyService::asInterface(binder);

	if(service == NULL)
	{
		cur_loge("error, service = NULL %s", __func__);
	}
	
	for(int32_t i = 0; i < 10; i++)
	{
		service->sendInt(-i);
		String8 str1 = service->getString();
		cur_logi("val = %d, str1 : %s", service->getInt(), str1.string());
 
		service->sendInt(i);
		String8 str2 = service->getString();
	    cur_logi("val = %d, str2 : %s", service->getInt(), str2.string());
	}
    service->sayHello();
	return 0;
}

 

  • 头文件

cur_log.h

#ifndef CUR_LOG_H
#define CUR_LOG_H
 
 
#include <android/log.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
 
 
#ifdef __cplusplus
extern "C" {
#endif
 
 
#undef  LOG_TAG
#define LOG_TAG "binder_test"
 
#define cur_logi(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)  /* 普通打印信息 */
#define cur_loge(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) /* 错误打印信息 */
// #define cur_logi(fmt, args...)  printf("I %s " fmt "\n", LOG_TAG, ##args)
// #define cur_loge(fmt, args...)  printf("E %s " fmt "\n", LOG_TAG, ##args)
#define cur_enter() cur_logi("enter %s", __func__)
#define cur_exit()  cur_logi("exit %s", __func__)
 
#ifdef __cplusplus
}
#endif
 
/* CUR_LOG_H */
#endif




  • 编译脚本

Android.mk



LOCAL_PATH := $(call my-dir)
 
####################
# MyService
####################
include $(CLEAR_VARS)
#LOCAL_MODULE_TAGSS := optional
#LOCAL_MODULE_CLASS := minrray
LOCAL_SRC_FILES := IMyService.cpp \
                     MyServer.cpp
 
LOCAL_C_INCLUDES += $(LOCAL_PATH) \
					$(TOP)/system/core/include/
 
LOCAL_SHARED_LIBRARIES := libc libutils libcutils liblog libbinder
 
LOCAL_MODULE := MyService
include $(BUILD_EXECUTABLE)
 
 
 
 
####################
# Myclient
####################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := IMyService.cpp \
					 MyClient.cpp
 
LOCAL_C_INCLUDES += $(LOCAL_PATH) \
					$(TOP)/system/core/include/
 
LOCAL_SHARED_LIBRARIES := libc libutils libcutils liblog libbinder
 
 
LOCAL_MODULE := MyClient
include $(BUILD_EXECUTABLE)
 
  • 注意点

frameworks/native/libs/binder/include/binder/IInterface.h  中kManualInterfaces  加入接口描述符,不然编译报错。

 

android App 调用binder c 服务实例

  • 接口文件定义

IMyService.java

package com.example.myapplication;
import android.os.IInterface;
import android.os.RemoteException;
import android.os.IBinder;
// Declare any non-default types here with import statements

public interface IMyService extends IInterface {
    static final String DESCRIPTOR = "com.example.myapplication.IMyService";

    void sendInt(int val) throws RemoteException;

    String getString() throws RemoteException;

    int getInt() throws RemoteException;

    void sayHello() throws RemoteException;

    static final int SEND_INT = IBinder.FIRST_CALL_TRANSACTION;
    static final int GET_STRING = IBinder.FIRST_CALL_TRANSACTION + 1;
    static final int GET_INT = IBinder.FIRST_CALL_TRANSACTION + 2;
    static final int SAY_HELLO = IBinder.FIRST_CALL_TRANSACTION + 3;
}
  • 接口客户端实现

MyServiceProxy.java

package com.example.myapplication;

import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;

public class MyServiceProxy implements IMyService {

    private android.os.IBinder mRemote;

    public MyServiceProxy(IBinder remote) {
        mRemote = remote;
    }


    public java.lang.String getInterfaceDescriptor() {
        return DESCRIPTOR;
    }

    @Override
    public IBinder asBinder() {
        return mRemote;
    }

    @Override
    public void sendInt(int val) throws RemoteException{
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(DESCRIPTOR);
        data.writeInt(val);
        mRemote.transact(SEND_INT,data,reply,0);
    }

    @Override
    public String getString() throws RemoteException{
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(DESCRIPTOR);
        mRemote.transact(GET_STRING,data,reply,0);
        String res = reply.readString();
        return res;
    }

    @Override
    public int getInt() throws RemoteException{
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(DESCRIPTOR);
        mRemote.transact(GET_INT,data,reply,0);
        int res = reply.readInt();
        return res;

    }

    @Override
    public void sayHello() throws RemoteException{
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(DESCRIPTOR);
        mRemote.transact(SAY_HELLO,data,reply,0);
        int res = reply.readInt();

        Log.e("Client","say hello " + res + " \n");
    }
}
  • 测试APP实现调用

两种方案获取服务

        IBinder jbinder = ServiceManager.getService("Myservice");
//        IBinder binder = null;
//        Class<?> forName = Class.forName("android.os.ServiceManager");
//        Method method = forName.getMethod("getService", String.class);
//        binder = (IBinder) method.invoke(null, "Myservice");
        
        IMyService  service = new MyServiceProxy(jbinder);
  • 注意点

1、关闭selinux ,否则报

SELinux : avc:  denied  { find } for pid=16336 uid=10246 name=cloudservice scontext=u:r:untrusted_app_29:s0:c246,c256,c512,c768 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0

2、MyService 服务需要放入手机/system/bin 下启动,放在/data/local/tmp 下需要修改文件权限,否则应用调用报SecurityException 异常;

3、不使用反射,可以自己创建android.so.ServiceManager 保证编译通过就可以,之后运行是调用的framework.jar 中类。

 

java 程序调用binder c

  • 编译jar包

JavaMain.java

package com.example.myapplication;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;

public class JavaMain {

    /**
     * Command-line entry point.
     *
     * @param args
     *            The command-line arguments
     * @throws RemoteException
     */
    public static void main(String[] args) throws RemoteException {
        System.out.println("==========Client starts===========");
        IBinder binder = ServiceManager.getService("Myservice");
        IMyService manager = new MyServiceProxy(binder);
        manager.sendInt(-1);
        System.out.println("" + manager.getString());
    }
}

 

IMyService.java、MyServiceProxy.java、JavaMain.java 三个文件放入com.example.myapplication 包路径下,编译JavaMain_lib.jar

  • 执行jar 包中main java 程序的可执行程序

JavaMain

# Script to start "am" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/JavaMain_lib.jar
exec app_process64 $base/bin com.example.myapplication.JavaMain "$@"

 

  • 编译脚本

Android.mk 

# Copyright 2008 The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := JavaMain_lib
LOCAL_MODULE_TAGS := optional

LOCAL_JAVACFLAGS := -encoding UTF-8
LOCAL_NO_EMMA_INSTRUMENT := true
LOCAL_NO_EMMA_COMPILE := true
LOCAL_MULTILIB := both
LOCAL_MODULE_PATH = $(PRODUCT_OUT)/system/framework
LOCAL_DEX_PREOPT := false

include $(BUILD_JAVA_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := JavaMain
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/bin
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES := JavaMain
include $(BUILD_PREBUILT)

 

  • 参考

https://blog.csdn.net/hubinbin595959/article/details/49491107

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值