android binder - 客户端(c++层) 调用 服务端(java层),服务端回调客户端 例子

学习了:
android binder - 客户端(java层) 调用 服务端(c++层) 例子
http://blog.csdn.net/ganyue803/article/details/41315733

android binder c++层-客户端(c++) 调用 服务端(c++) 例子
http://blog.csdn.net/ganyue803/article/details/41315519

android binder c++层 - 回调客户端服务 - 客户端(c++层) 调用 服务端(c++层) 例子,服务端回调客户端服务
http://blog.csdn.net/ganyue803/article/details/41316707

想进一步学习 客户端(c++层) 调用 服务端(java层)的情况。动手写一个例子。

服务端:
文件结构如下图:
这里写图片描述
创建一个app工程,添加一个MyBinderService作为Binder的服务端,这个服务可能是Launcher中没有图标启动,作为一个开机自启动的服务。因此这里startService在Application中处理。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lzl.bindertest"
    android:sharedUserId="android.uid.system">

    <application android:name=".BinderTestApplication"
        android:allowBackup="true" android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true" android:theme="@style/AppTheme"
        >
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="com.lzl.bindertest.MyBinderService"/>
    </application>

</manifest>

MyBinderService.java

package com.lzl.bindertest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * Created by lzl on 2017/7/6.
 */

public class MyBinderService  extends Service{
    final String TAG = "bindertest";
    final String MyBinderService_name = "lzl.mybinderservice";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    IMyBinderService.Stub mBinder = new IMyBinderService.Stub(){
        //当客户端发送数据过来时,onTransact函数开始执行
        @Override
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            switch (code) {
                case Stub.TRANSACTION_mytest:
                    int dataSize = data.dataSize();
                    int replySize = reply.dataSize();
                    Log.d(TAG, "dataSize:" + dataSize + ", replySize:" + replySize);

                   //读取客户端发送的序列化数据
                    int streamType = data.readInt();
                    int pid = data.readInt();

                    int writeNum = mytest(streamType, pid);

                    // 写在parcel序列化数据的首位,表示没有错误,一会客户端会检测该数据位
                    reply.writeInt(0);

                    Log.d(TAG, "reply.writeInt:" + writeNum);
                    reply.writeInt(writeNum); //服务端发送给客户端数据
                    break;
            }
            return true;
        }

        @Override
        public int mytest(int streamType, int pid) throws RemoteException {
        // do something...
            int result = 100return result;
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "============MyBinderService onCreate==========");
        // 将服务添加到ServiceManager管理,这里普通APP无法调用接口,
        // 需要工程导入android源码编译好的framework.jar中间包文件
        ServiceManager.addService(MyBinderService_name, mBinder);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
}

BinderTestApplication.java

package com.lzl.bindertest;

import android.app.Application;
import android.content.Intent;
import android.util.Log;

/**
 * Created by lzl on 2017/7/6.
 */

public class BinderTestApplication extends Application {
    final String TAG = "bindertest";
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "=========BinderTestApplication  onCreate=========");

        startService(new Intent(this, MyBinderService.class));
    }
}

MainActivity.java 不做处理

package com.lzl.bindertest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        final String TAG = "bindertest";
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "============MainActivity onCreate==========");

    }
}

IMyBinderService.aidl

// IMyBinderService.aidl
package com.lzl.bindertest;

// Declare any non-default types here with import statements

interface IMyBinderService {
    int mytest(int streamType, int pid);
}

添加IMyBinderService.aidl后clean project或rebuild project将自动生成对应的IMyBinderService.java

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: F:\\Work\\MyDemo\\bindertest\\src\\main\\aidl\\com\\lzl\\bindertest\\IMyBinderService.aidl
 */
package com.lzl.bindertest;
// Declare any non-default types here with import statements

public interface IMyBinderService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.lzl.bindertest.IMyBinderService
{
private static final java.lang.String DESCRIPTOR = "com.lzl.bindertest.IMyBinderService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.lzl.bindertest.IMyBinderService interface,
 * generating a proxy if needed.
 */
public static com.lzl.bindertest.IMyBinderService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.lzl.bindertest.IMyBinderService))) {
return ((com.lzl.bindertest.IMyBinderService)iin);
}
return new com.lzl.bindertest.IMyBinderService.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_mytest:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.mytest(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.lzl.bindertest.IMyBinderService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public int mytest(int streamType, int pid) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(streamType);
_data.writeInt(pid);
mRemote.transact(Stub.TRANSACTION_mytest, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}

//这里的函数名ID需要记住,后面在客户端会根据这个ID找到mytest函数。
static final int TRANSACTION_mytest = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int mytest(int streamType, int pid) throws android.os.RemoteException;
}

编译好工程生成app, 安装启动,MyBinderService就添加到系统中了。

接下来实现客户端,文件如下:
这里写图片描述

Android.mk

# Copyright 2009 The Android Open Source Project

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
    nativeBinderTest.cpp \
    IMyBinderManager.cpp

LOCAL_SHARED_LIBRARIES := libc \
    libcutils \
    libbinder \
    libutils

LOCAL_LDLIBS :=-llog

LOCAL_MODULE:= nativebinder

LOCAL_MODULE_TAGS := debug

LOCAL_CFLAGS : = -DRIL_SHLIB

include $(BUILD_EXECUTABLE)

IMyBinderManager.h

#ifndef IMYBINDERMANAGER_H_H
#define IMYBINDERMANAGER_H_H
#include <binder/IServiceManager.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IInterface.h>
#include <binder/Binder.h>
#include <private/binder/binder_module.h>

using namespace android;
namespace android
{
    class IMyBinderManager : public IInterface
    {
    public:
        DECLARE_META_INTERFACE(MyBinderManager); // declare macro
        virtual int mytest(int streamType, int pid)=0;
    };

    enum
    {
        MYTEST = IBinder::FIRST_CALL_TRANSACTION+0,
    };

    class BpMyBinderManager: public BpInterface<IMyBinderManager> {
    public:
        BpMyBinderManager(const sp<IBinder>& impl);
        virtual int mytest(int streamType, int pid);
    };
}
#endif

IMyBinderManager.cpp

#include "IMyBinderManager.h"

namespace android
{
    IMPLEMENT_META_INTERFACE(MyBinderManager, "com.lzl.bindertest.IMyBinderService");
}

nativeBinderTest.cpp

// Copyright 2009 The Android Open Source Project
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <dirent.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#include <utime.h>
#include <sys/stat.h>
#include <stdint.h>
#include<android/log.h>

#include "IMyBinderManager.h"


using namespace android;

#define BINDERTEST_DEBUG
#define TAG "bindertest" 

#ifdef BINDERTEST_DEBUG
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)
#else
#define LOGD(...) do { } while(0)    
#define LOGI(...) do { } while(0)    
#define LOGW(...) do { } while(0)
#define LOGF(...) do { } while(0)
#endif
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)
#endif

#define MY_BINDER_SERIVCE_NAME "lzl.mybinderservice"

namespace android
{
    BpMyBinderManager::BpMyBinderManager(const sp<IBinder>& impl) :
            BpInterface<IMyBinderManager>(impl) {
    }

    int BpMyBinderManager::mytest(int streamType, int pid) {
            LOGW("Client call server mytest method\n");
            Parcel data, reply;
                data.writeInt32(streamType);
        data.writeInt32(pid);

            remote()->transact(MYTEST, data, &reply);

            int code = reply.readExceptionCode();//读取服务器返回的错误码
            int result;
            reply.readInt32(&result);//读取服务端返回的数据
            LOGW("Server exepction code: %d\n", code);
        return result;
    }
}

int main (int /*argc*/, char **/*argv*/)
{  
    int socketfd;
    int tempBuf[2];
    tempBuf[0] = 12;        //streamType
    tempBuf[1] = 198;       //pid

    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder = sm->getService(String16(MY_BINDER_SERIVCE_NAME));
    if (binder == NULL){
     LOGW( "Client can't find Service" );
       return -1;
    } else {
     LOGW( "Client find Service" );
    }

    sp<IMyBinderManager> service = interface_cast<IMyBinderManager>(binder);
    int result = service->mytest(tempBuf[0], tempBuf[1]); //客户端调用服务端函数
    LOGW("MyBinderManager client   result:%d", result);



    return 0;
}

在Android系统源码环境下编译客户端程序生成nativebinder bin文件,将该bin文件push到机器中,
命令执行该bin文件,查看log。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Binder 中,服务端可以通过 IBinder 类中的 transact() 方法向客户端发送消息。下面是一个简单的示例代码,演示了如何在服务端中向客户端发送消息: 1.服务端代码 ```java public class MyService extends Service { private MyBinder mBinder = new MyBinder(); public class MyBinder extends Binder { public void sendMessage(String message) { Parcel data = Parcel.obtain(); data.writeString(message); // 获取客户端的 IBinder IBinder clientBinder = getApplicationContext() .getServiceManager() .getService("com.example.client"); try { clientBinder.transact(0, data, null, IBinder.FLAG_ONEWAY); } catch (RemoteException e) { e.printStackTrace(); } finally { data.recycle(); } } } @Override public IBinder onBind(Intent intent) { return mBinder; } } ``` 在服务端代码中,我们定义了一个 MyBinder 对象,并实现了 sendMessage() 方法。在 sendMessage() 方法中,我们创建了一个 Parcel 对象,将消息写入 Parcel 中,然后获取客户端的 IBinder 对象,并通过 transact() 方法向客户端发送消息。 2.客户端代码 ```java public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String message = intent.getStringExtra("message"); Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } } ``` 在客户端代码中,我们定义了一个 BroadcastReceiver 对象,用于接收服务端发送的消息。在 onReceive() 方法中,我们获取到消息,并使用 Toast 将其显示出来。 需要注意的是,服务端在通过 transact() 方法向客户端发送消息时,需要获取客户端的 IBinder 对象。在上面的示例代码中,我们使用了 getApplicationContext().getServiceManager().getService("com.example.client") 来获取客户端的 IBinder 对象,其中 "com.example.client" 是客户端的包名。如果客户端没有在系统服务中注册,服务端将无法获取客户端的 IBinder 对象,从而无法向客户端发送消息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值