该小节我们将使用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目录下,然后修改文件:
-
把 IHelloService.aidl 放入 frameworks/base/core/java/android/os
-
修改 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 [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: [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); } } } }
该代码没有进行测试编译,下小节进行测试编译。