该小节我们将使用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);
}
}
}
}
该代码没有进行测试编译,下小节进行测试编译。