05.Binder系统:第8课第2节_Binder系统_JAVA实现_hello服务_编程

该小节我们将使用java实现一个hello服务,曾经我们讲解硬件访问服务的时候,实现一个LED服务,那个时候我们只知道照葫芦画瓢,并不知道其中的原理,该小节我们写出hello服务之后,相信你对他的原理就比较了解了。

c++编写

先回顾一下,我们使用C++编写的Hello服务。
首先定义一个IHelloService.h接口,其中有两个函数sayhello与sayhello_to,然后在server端实现这两个函数,client端使用这两个函数,下面是一个流程草图:

在这里插入图片描述

实现服务函数时在BnHelloService中,使用函数是在BpHelloService中实现。实现了则两个类之后,我们再编写
test_server.cpp文件:通过addservice添加服务,然后循环读取,解析,调用BnHelloService实现的函数。
test_client.cpp文件:通过getService获取服务,然后调用BpHelloService中的sayhello或者sayhello_to函数。

现在我们使用C++实现hello程序,原理也是类似的。

java实现

下面是使用java实现的一个草图:
在这里插入图片描述
收我们要定义一个接口aidl文件,然后实现两个方法sayhello与sayhello_to。然后编译生成IHelloService.java,其中声明有接口,定义了一个stab与proxy类。IHelloService是自动生成的,不需要我们进行编写。那么server与client端分别会做什么呢?
server:定义一个HelloService类,其中 实现sayhello与sayhello_to两个方法。
client:代理类已经有了,直接使用即可。

后面我们会编写
TestServer.java:,在main函数中首先调用addservice,然后进入循环。循环还是读取,解析数据,调用对应函数,然后返回,不过该段代码不需要我们编写。
TestClient.java:首先在main方法中,通过getService获取服务,然后调用sayhello或者sayhello_to。

现在我们开始编写程序

IHelloService.aidl


/** {@hide} */
interface IHelloService
{
	void sayhello();
	int sayhello_to(String name);
}

frameworks\base\core\java\android\os目录下,然后修改文件:

  1. 把 IHelloService.aidl 放入 frameworks/base/core/java/android/os

  2. 修改 frameworks/base/Android.mk 添加一行
    core/java/android/os/IVibratorService.aidl
    + core/java/android/os/IHelloService.aidl \

执行命令
mmm frameworks/base
如果报错先执行
mmm frameworks/base/core/res/

然后其会生成out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/IHelloService.java文件
代码如下:

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: frameworks/base/core/java/android/os/IHelloService.aidl
 */
/** {@hide} */
public interface IHelloService extends android.os.IInterface
{
    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements IHelloService
    {
        private static final java.lang.String DESCRIPTOR = "IHelloService";
        /** Construct the stub at attach it to the interface. */
        public Stub()
        {
            this.attachInterface(this, DESCRIPTOR);
        }
        /**
         * Cast an IBinder object into an IHelloService interface,
         * generating a proxy if needed.
         */
        public static IHelloService asInterface(android.os.IBinder obj)
        {
            if ((obj==null)) {
            return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin!=null)&&(iin instanceof IHelloService))) {
            return ((IHelloService)iin);
            }
            return new IHelloService.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_sayhello:
                {
                    data.enforceInterface(DESCRIPTOR);
                    this.sayhello();
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_sayhello_to:
                {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    int _result = this.sayhello_to(_arg0);
                    reply.writeNoException();
                    reply.writeInt(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        
        private static class Proxy implements IHelloService
        {
            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 void sayhello() throws android.os.RemoteException
            {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0);
                    _reply.readException();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
            @Override public int sayhello_to(java.lang.String name) 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.writeString(name);
                    mRemote.transact(Stub.TRANSACTION_sayhello_to, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                    return _result;
            }
        }
        
        static final int TRANSACTION_sayhello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_sayhello_to = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
            
    }
    
    public void sayhello() throws android.os.RemoteException;
    public int sayhello_to(java.lang.String name) throws android.os.RemoteException;
}

可以看到IHelloService接口中存在:
stub类:包含一个onTransact函数,他会分辨收到的数据,然后代用sayhello或者sayhello_to
Proxy类:提供有sayhello()与sayhello_to()两个函数,他们会构造数据,然后发送给server。

下面我们要实现服务类,即HelloService.java

HelloService.java


/* 实现Hello服务的函数 */

public class HelloService extends IHelloService.Stub {
    private static final String TAG = "HelloService";
    private int cnt1 = 0;
    private int cnt2 = 0;

    public void sayhello() throws android.os.RemoteException {
        cnt1++;
        Slog.i(TAG, "sayhello : cnt = "+cnt1);
    }
    
    public int sayhello_to(java.lang.String name) throws android.os.RemoteException {
        cnt2++;
        Slog.i(TAG, "sayhello_to "+name+" : cnt = "+cnt2);
        return cnt2;
    }
}

TestServer.java


/* 实现Hello服务的函数 */

public class HelloService extends IHelloService.Stub {
    private static final String TAG = "HelloService";
    private int cnt1 = 0;
    private int cnt2 = 0;

    public void sayhello() throws android.os.RemoteException {
        cnt1++;
        Slog.i(TAG, "sayhello : cnt = "+cnt1);
    }
    
    public int sayhello_to(java.lang.String name) throws android.os.RemoteException {
        cnt2++;
        Slog.i(TAG, "sayhello_to "+name+" : cnt = "+cnt2);
        return cnt2;
    }
}


TestClient.java


/* 1. getService
 * 2. 调用服务的sayhello,sayhello_to
 *
 */

/* test_client <hello|goodbye> [name] */

public class TestClient {
    private static final String TAG = "TestClient";

    public static void main(String args[])
    {
        if (args.length == 0)
        {
            System.out.println("Usage: need parameter: <hello|goodbye> [name]");
            return;
        }

        if (args[0].equals("hello"))
        {
            /* 1. getService */
            IBinder binder = ServiceManager.getService("hello");
            if (binder == null)
            {
                System.out.println("can not get hello service");
                Slog.i(TAG, "can not get hello service");
                return;
            }

            IHelloService svr = IHelloService.Stub.asInterface(binder);

            if (args.length == 1)
            {
                svr.sayhello();
                System.out.println("call sayhello");
                Slog.i(TAG, "call sayhello");
            }
            else
            {
                int cnt = svr.sayhello_to(args[1]);
                System.out.println("call sayhello_to "+args[1]+" : cnt = "+cnt);
                Slog.i(TAG, "call sayhello_to "+args[1]+" : cnt = "+cnt);
            }
        }
    }
}

该代码没有进行测试编译,下小节进行测试编译。

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/89156789