美文网首页
Android Binder通信原理--07:Framework

Android Binder通信原理--07:Framework

作者: DarcyZhou | 来源:发表于2023-10-19 07:52 被阅读0次

本文转载自:Android10.0 Binder通信原理(七)-Framework binder示例

本文基于Android 10.0源码分析

1.摘要

  本节主要来讲解Android10.0 Binder在Framework中的示例。

2.Demo示例说明

(1)Server进程目录结构

Server
├─src
│  └─com
│       └─android
│               └─server
│                   ├─Server.java
│                   ├─MyService.java
│                   └─IMyService.java
├─Android.mk
└─serverTest

(2)Client进程目录结构

Client
├─src
│  └─com
│       └─android
│               └─client
│                   ├─Client.java
│                   ├─MyServiceProxy.java
│                   └─IMyService.java
├─Android.mk
└─clientTest

3.Demo 创建

3.1 Server端创建服务,提供接口

(1)文件说明

文件 说明
Server.java Server入口
MyService.java 服务实体
IMyService.java 服务接口
Android.mk 编译文件
serverTest 可执行程序,保存在/system/bin中,用来运行JAVA进程

(2)Server.java:服务入口

package com.android.server;
import android.os.Looper;
import android.os.ServiceManager;

public class Server {
    public static void main(String args[]){
        System.out.println("Server service Start");
        Looper.prepareMainLooper(); //开启循环执行
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
        /*注册服务*/
        ServiceManager.addService("MyTestService", new MyService());
        Looper.loop();
    }
}

(3)MyService.java:服务实体

package com.android.server;

import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.IInterface;
import android.os.RemoteException;

public class MyService extends Binder implements IMyService{ 
    private String value;
    public MyService() {
        attachInterface(this, IMyService.descriptor);
    }

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

    public static IMyService asInterface(IBinder obj) {
        if ((obj == null)) {
            return null;
        }

        IMyService in = (IMyService)obj.queryLocalInterface(IMyService.descriptor);
        if (in != null) {
            return in;
        }

        return null;
    }

       /*接收远程消息,进行处理*/
    @Override
    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
            case SET_VALUE_TRANSACTION: {
                data.enforceInterface(IMyService.descriptor);
                String str = data.readString(); //收到Client的数据
                setValue(str);
                reply.writeNoException();
                return true;
            }
            case GET_VALUE_TRANSACTION: {
                data.enforceInterface(IMyService.descriptor);
                String str = getValue();
                reply.writeNoException();
                reply.writeString(str); //把返回的数据写入Parcel,Client会进行接收
                return true;
            }

        }
        return super.onTransact(code, data, reply, flags);
    }

       /*服务的实现方法*/
     @Override
    public void setValue(String str)  throws RemoteException {
        System.out.println("Client calling : setValue is " + str);
        this.value = str;
    }

        @Override
    public String getValue() throws RemoteException {
        System.out.println("Client calling : getValue is " + value);
        return value;
    }
}

(4)IMyService.java:接口

package com.android.server;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;

public interface IMyService extends IInterface {
    static final  String descriptor = "com.android.server";
    public void setValue(String str) throws RemoteException;
    public String getValue() throws RemoteException;

    static final int SET_VALUE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
    static final int GET_VALUE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
}

(5)Android.mk:编译文件

LOCAL_PATH:= $(call my-dir)

#1.编译成serverTest.jar,编译到/system/framework中
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := serverTest
include $(BUILD_JAVA_LIBRARY)

#2.编译成serverTest进程,最终放入到/system/bin中,源文件是当前目录下的serverTest
include $(CLEAR_VARS)
LOCAL_MODULE := serverTest
LOCAL_SRC_FILES := serverTest
LOCAL_MODULE_PATH := $(TARGET_OUT)/bin
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)

(6)serverTest:可执行文件,最终会拷贝到/system/bin中

#!/system/bin/sh
# Script to start "serverTest" on the device
#
base=/system
export CLASSPATH=$base/framework/serverTest.jar
exec app_process $base/bin com.android.server.Server "$@"

3.2 Client端获取服务,数据通信

(1)文件说明

文件 说明
Client.java Client入口
MyServiceProxy.java 服务代理
IMyService.java 服务接口
Android.mk 编译命令
clientTest 可执行程序,保存在/system/bin中,用来运行JAVA进程

(2)Client.java:Client入口

package com.android.client;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;

public class Client {

    public static void main(String[] args) throws RemoteException {
        System.out.println("Client start");
           //获取服务
        IBinder binder = ServiceManager.getService("MyTestService");
        //创建MyServiceProxy对象
        IMyService myService = new MyServiceProxy(binder);
        //通过MyServiceProxy对象调用接口的方法
        myService.setValue("Hello binder!");
        String str = myService.getValue();
        System.out.println("The value from server binder is " + str);
        System.out.println("Client end");
    }
}

(3)MyServiceProxy.java:服务代理

package com.android.client;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;

public class MyServiceProxy implements IMyService {
    private IBinder mRemote;

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

    public String getInterfaceDescriptor() {
        return IMyService.descriptor;
    }

    /*接口方法实现*/
    @Override
    public void setValue(String str) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        try {
            data.writeInterfaceToken(IMyService.descriptor);
            data.writeString(str);//把str数据写入Parcel,服务端会进行解析
            mRemote.transact(SET_VALUE_TRANSACTION, data, reply, 0);//发送的code:SET_VALUE_TRANSACTION
            reply.readException();
        } finally {
            reply.recycle();
            data.recycle();
        }
    }

    @Override
    public String getValue() throws RemoteException {
        String str;
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        try {
            data.writeInterfaceToken(IMyService.descriptor);
            mRemote.transact(GET_VALUE_TRANSACTION, data, reply, 0);//发送的code:GET_VALUE_TRANSACTION
            reply.readException();
            str = reply.readString();//读取服务端发来的内容
        } finally {
            reply.recycle();
            data.recycle();
        }
        return str;
    }

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

}

(4)Android.mk:编译文件

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := clientTest
include $(BUILD_JAVA_LIBRARY)

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

(5)clientTest:可执行程序

#!/system/bin/sh
# Script to start "clientTest" on the device
#
base=/system
export CLASSPATH=$base/framework/clientTest.jar
exec app_process $base/bin com.android.client.Client "$@"

4.编译验证

4.1 编译方式

把上述代码文件夹push到/frameworks/base/cmds/中
source build.sh xxx   #注:xxx为编译项目名
cd /frameworks/base/cmds/
mmm server
mmm client

4.2 结果验证

adb push ..../out/target/..../system/framework/serverTest.jar /system/framework
adb push ..../out/target/..../system/framework/clientTest.jar /system/framework
adb push ..../out/target/..../system/bin/serverTest. /system/bin
adb push ..../out/target/..../system/bin/clientTest. /system/bin

==>开启两个cmd终端,执行adb shell
server端执行:/system/bin/serverTest
Client端执行:/system.bin/clientTest 

运行结果:

(1)Client

Binder7-1.png

(2)Server

Binder7-2.png

相关文章

网友评论

      本文标题:Android Binder通信原理--07:Framework

      本文链接:https://www.haomeiwen.com/subject/nrxbbdtx.html