android的JNI开发有两种,一种是基于应用程序的,一种是基于系统框架的。
java文件,指定native函数来实现接口的功能
基于应用程序的比较简单,之前已经有所了解,今天实践了一下基于系统框架的JNI读取文件的操作。
效果图:
总体框架:
1.应用程序调用API
2.JAVA层编写API接口,调用JNI层函数
3.JNI实现读取文件的操作,并根据要求返回读取的文件
主要层次为:
1.应用程序调用API
- String mstr = helloService.getText(); //api for read file
- new AlertDialog.Builder(JniTestActivity.this)
- .setMessage(mstr)
- .show();
- Log.i(JAVA_DEBUG, "done");
- } catch (RemoteException e) {
- Log.e(JAVA_DEBUG, "Remote Exception while reading value from helloService.sayHello().");
- }
2.JAVA层编写API接口,调用JNI层函数
aidl文件,定义接口规范:
- interface IHelloService {
- String getText();
- }
- import android.content.Context;
- import android.os.IHelloService;
- import android.util.Slog;
- public class HelloService extends IHelloService.Stub {
- private static final String TAG = "HelloService";
- public String getText() {
- return getText_native();
- }
- private static native String getText_native();
- };
3.JNI实现读取文件的操作,并根据要求返回读取的文件
- #include "jni.h"
- #include "JNIHelp.h"
- #include "android_runtime/AndroidRuntime.h"
- #include <utils/misc.h>
- #include <utils/Log.h>
- #include <stdio.h>
- #include <fcntl.h>
- namespace android
- {
- #define TEXT_SUPPLY_PATH "/system/usr/getText.txt"
- #define PATH_MAX_LEN 4096
- static int readFromFile(const char* path, char* buf, size_t size);
- static jstring hello_getText(JNIEnv* env, jobject clazz) {
- char path[PATH_MAX_LEN];
- char buf[50];
- LOGI("Hello JNI: get text from device.");
- snprintf(path, sizeof(path), "%s", TEXT_SUPPLY_PATH);
- int length = readFromFile(path, buf, sizeof(buf));
- LOGI("Hello JNI: file length = %d.", length);
- return (env)->NewStringUTF(buf);
- }
- static int readFromFile(const char* path, char* buf, size_t size)
- {
- if (!path)
- return -1;
- int fd = open(path, O_RDONLY, 0);
- if (fd == -1) {
- LOGE("Could not open '%s'", path);
- return -1;
- }
- size_t count = read(fd, buf, size);
- if (count > 0) {
- count = (count < size) ? count : size - 1;
- while (count > 0 && buf[count-1] == '\n') count--;
- buf[count] = '\0';
- } else {
- buf[0] = '\0';
- }
- close(fd);
- return count;
- }
- static const JNINativeMethod method_table[] = {
- {"getText_native", "()Ljava/lang/String;", (void*)hello_getText},
- };
- int register_android_server_HelloService(JNIEnv *env) {
- return jniRegisterNativeMethods(env, "com/android/server/HelloService", method_table, NELEM(method_table));
- }
- };
注意事先把文件准备把,存放的路径为:TEXT_SUPPLY_PATH "/system/usr/getText.txt"
主要是以上3个层次,省略了*.mk文件的修改细节,了解原理即可。