您的位置:首页 > 移动开发 > Android开发

Android HAL开发之基于Service的HAL设计

2013-04-22 17:30 423 查看
在上一篇文章中,我介绍了一种应用程序直接调用JNI库的HAL设计方法,该方法虽然简单,但是不符合Android的框架结构,下面我们介绍一种通过Service提供接口给应用程序的设计方法,结构如下:

HAL stub <-> JNI 库 <-> JAVA Service <->JAVA 应用程序。

HAL stub的设计和上文一样,JNI库的设计中唯一需要修改的地方就是register_mokoid_server_LedService函数,在上文中该JNI库直接提供给应用程序使用,而这里,JNI库是提供接口给JAVA Service使用,修改如下:
int register_mokoid_server_LedService(JNIEnv* env) {
//static const char* const kClassName =
//  "com/mokoid/LedClient/LedClient";
static const char* const kClassName =
"com/mokoid/server/LedService";
jclass clazz;

/* look up the class */
clazz = env->FindClass(kClassName);
if (clazz == NULL) {
LOGE("Can't find class %s\n", kClassName);
return -1;
}

/* register all the methods */
if (env->RegisterNatives(clazz, gMethods,
sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
{
LOGE("Failed registering methods for %s\n", kClassName);
return -1;
}

/* fill out the rest of the ID cache */
return 0;
}


在这里,我们的JNI库会提供给com.mokoid.server.LedService类使用,而不是上文中的应用程序com.mokoid.LedClient.LedClient类。该JNI库最后会被编译成libmokoid_runtime.so。

下面我们再看看com.mokoid.server.LedService的实现:
public final class LedService {

static {
System.load("/system/lib/libmokoid_runtime.so");
}

public LedService() {
Log.i("LedService", "Go to get LED Stub...");
_init();
}

/*
* Mokoid LED native methods.
*/
public boolean setOn(int led) {
Log.i("MokoidPlatform", "LED On");
return _set_on(led);
}

public boolean setOff(int led) {
Log.i("MokoidPlatform", "LED Off");
return _set_off(led);
}

private static native boolean _init();
private static native boolean _set_on(int led);
private static native boolean _set_off(int led);
}


这个Service的实现和上文中的应用程序的实现比较类似,也是通过System.load装载JNI库,然后就可以在自己的方法中使用JNI接口,该Service最后会被编译成mokoid.jar,且位于/system/framework中,值得注意的是,应用程序如果要调用该Service,必须在/etc/perimissions中有一个xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<library name="com.mokoid.server"
file="/system/framework/mokoid.jar"/>
</permissions>


通过这个文件,应用程序就可以使用com.mokoid.server来找到mokoid.jar文件。

我们最后再来看看应用程序的实现:
package com.mokoid.LedClient;
import com.mokoid.server.LedService;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class LedClient extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Call an API on the library.
LedService ls = new LedService();
ls.setOn(1);
ls.setOff(2);

TextView tv = new TextView(this);
tv.setText("LED 1 is on. LED 2 is off.");
setContentView(tv);
}
}


这里通过import com.mokoid.server.LedService来使用上面设计的LedService,然后通过new LedService()来得到Service的实例,之后就可以直接调用该Service的方法来控制Led了。

AndroidManifest.xml如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mokoid.LedClient">

<application>

<!-- This tells the system about the custom library used by the
application, so that it can be properly loaded and linked
to the app when the app is initialized. -->
<uses-library android:name="com.mokoid.server" />

<activity android:name="LedClient">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>


注意,uses-library告诉了系统该程序需要调用的非系统库,既上面我们设计的Service库。

本文出自 “Mobile and Linux
Deve..” 博客,请务必保留此出处/article/4442094.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: