写好底层的库,接下来就是写应用程序使用或验证了。
前面也介绍了,应用程序访问jni库,有多种方法,最简单的就是直接调用,其次是用service,再次为service manager
1 直接加载。
这有点儿像从三楼直接跳下来。其实java本来就有调用原生代码的接口。android开发还包含有ndk开发,这个就是直接用c来做应用程序。
1.1 testjni1.java
在与framwork同层目录下,创建app目录,mkdir app
再在app目录下,创建dirload/src/com/ask/目录,生成testjni1.java,内容如下:
package com.ask.testjni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class testjni1 extends Activity
{
static
{
//System.load("/system/lib/libaskgpio.so");
System.load("/system/lib/libaskgpio");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Call an API on the library.
_gpio_init();
_gpio_set(1);
_gpio_clr(2);
TextView tv = new TextView(this);
tv.setText("gpio 1 is set to 1. gpio 2 is set to 0.");
setContentView(tv);
}
private static native boolean _gpio_init();
private static native boolean _gpio_set(int gpio);
private static native boolean _gpio_clr(int gpio);
}
说明:System.load("/system/lib/libaskgpio");有实际测试中这样加载可能不成功,要定居这样System.load("/system/lib/libaskgpio.so");
1.2 Android.mk编写,保存在dirload目录下
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := user
# This is the target being built.
LOCAL_PACKAGE_NAME := testjni1
# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
# Link against the current Android SDK.
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
1.3 再写AndroidManifest.xml,保存至dirload目录下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ask.testjni1">
<application>
<activity android:name="testjni1">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
最后编译,将在out/target/product/generic/system/app/生成testjni1.apk文件。
2 调用service方式
2.1再在app目录下,创建serviceload/src/com/ask/目录,生成serviceload.java,内容如下:
package com.ask.serviceload;
import com.ask.server.serviced; //注意不是GpioService
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class serviceload extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Call an API on the library.
serviced sd = new serviced();
sd.GpioSet(1);
sd.GpioClr(2);
TextView tv = new TextView(this);
tv.setText("gpio 1 is set. gpio 2 is clr.");
setContentView(tv);
}
}
这里new一个serviced,这时将会加载jni的库,然后调用serviced里的api函数GpioSet和GpioClr
2.2 编写Android.mk文件,保存至serviceload目录下
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := user
# This is the target being built.
LOCAL_PACKAGE_NAME := serviceload
# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
# Link against the current Android SDK.
LOCAL_SDK_VERSION := current
# Also link against our own custom library.
LOCAL_JAVA_LIBRARIES := ask
include $(BUILD_PACKAGE)
2.3 再写AndroidManifest.xml,保存至serviceload目录下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ask.GpioClient">
<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.ask.serviced" />
<activity android:name="serviceload">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
最后编译,将在out/target/product/generic/system/app/生成serviceload.apk文件。
2.4 运行此程序由于用到serviceload类,因此还要在/etc/permission下,增加一个permission,如下
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<library name="com.ask.serviced"
file="/system/framework/ask.jar"/>
</permissions>
文件名可为com.ask.serviced.xml
3 通过service manager调用jni
3.1 在app目录下,创建managerload/src/com/ask/目录
3.1.1 生成gpio system service类,文件名GpioSystemServer.java
这个类的生成主要是供managerload调用,内容如下
package com.ask.GpioSystemServer;
import com.ask.server.GpioService;
import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Log;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
public class GpioSystemServer extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onStart(Intent intent, int startId) {
Log.i("GpioSystemServer", "Start GpioService...");
/* Please also see SystemServer.java for your interests. */
GpioService gs = new GpioService();
try {
ServiceManager.addService("gpio", gs);
} catch (RuntimeException e) {
Log.e("GpioSystemServer", "Start GpioService failed.");
}
}
}
3.1.2 生成managerload.java,内容如下:
package com.ask.managerload;
import ask.hardware.GpioManager;
import com.ask.server.GpioService;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Button;
import android.content.Intent;
import android.view.View;
public class managerload extends Activity implements View.OnClickListener {
private GpioManager mGpioManager = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Start LedService in a seperated process.
startService(new Intent("com.ask.systemserver"));
Button btn = new Button(this);
btn.setText("Click to turn gpio 1 set 1");
btn.setOnClickListener(this);
setContentView(btn);
}
public void onClick(View v) {
// Get LedManager.
if (mGpioManager == null) {
Log.i("LedTest", "Creat a new mGpioManager object.");
mGpioManager = new GpioManager();
}
if (mGpioManager != null) {
Log.i("managerload", "Got GpioManager object.");
}
mGpioManager.GpioSet(1);
TextView tv = new TextView(this);
tv.setText("gpio 1 is set 1.");
setContentView(tv);
}
}
3.3 编写Android.mk文件
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := user
# This is the target being built.
LOCAL_PACKAGE_NAME := managerload
# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
# Link against the current Android SDK.
LOCAL_SDK_VERSION := current
# Also link against our own custom library.
LOCAL_JAVA_LIBRARIES := ask framework
# We need to assign platform key to use ServiceManager.addService.
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
3.4 同2.4一样,在/etc/permission下增加一个xml文件。
运行此程序由于用到serviceload类,因此还要在/etc/permission下,增加一个permission,如下
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<library name="com.ask.server"
file="/system/framework/ask.jar"/>
</permissions>
文件名可为com.ask.GpioService.xml