android binder

来源:互联网 发布:谜画之塔mac版 编辑:程序博客网 时间:2024/06/05 17:28

学习了:
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.aidlpackage com.lzl.bindertest;// Declare any non-default types here with import statementsinterface 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 statementspublic 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 ProjectLOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= \    nativeBinderTest.cpp \    IMyBinderManager.cppLOCAL_SHARED_LIBRARIES := libc \    libcutils \    libbinder \    libutilsLOCAL_LDLIBS :=-llogLOCAL_MODULE:= nativebinderLOCAL_MODULE_TAGS := debugLOCAL_CFLAGS : = -DRIL_SHLIBinclude $(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。