本文共 4082 字,大约阅读时间需要 13 分钟。
12年的时候写过JNI但是又忘记得差不多了,现在重新写了一次,发现碰到了几个问题,写下来记录一下
第一步
应用程序java代码
package com.example.helloworld;import java.util.Calendar;import android.os.Bundle;import android.app.Activity;import android.app.AlarmManager;import android.util.Log;public class AlarmTest extends Activity{ AlarmManager aManager; Calendar currentTime = Calendar.getInstance(); public static final int POWER_OFF_WAKE_UP = 8;//用来设置关机启动的参数 平台这边已经设置好了 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("weiqifa", test()); } public native String test(); static { try{ Log.i("JNI", "Trying to load libhelloworld.so"); System.loadLibrary("helloWorld"); }catch(UnsatisfiedLinkError ule){ Log.e("JNI", "Warning : could not load the libhelloworld.so"); } }}
编译一下,可以是eclipse编译,也可以是java命令编译
编译后有下面的代码结构和目录
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls AndroidManifest.xml classes classes.dex dexedLibs helloWorld.apk res resources.ap_ weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
第二步
生成共享头文件 这一步是最关键的关系到成功和失败
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -d header -classpath classes -jni com.example.helloworld.AlarmTest weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
这个命令比较关键 javah -d header 指的是在当前目录下面生成这个头文件,-classpath是指定classes的目录就是第一步里面生成的
-jni指的是生成jni头文件 com.example.helloworld这个是包名 AlarmTest是类名 这些都不能有错
生成后如下
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls AndroidManifest.xml classes classes.dex dexedLibs header helloWorld.apk res resources.ap_ weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls header/ com_example_helloworld_AlarmTest.h weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ cat header/com_example_helloworld_AlarmTest.h /* DO NOT EDIT THIS FILE - it is machine generated */#include刚开始不知道,运行经常出错如下:/* Header for class com_example_helloworld_AlarmTest */#ifndef _Included_com_example_helloworld_AlarmTest#define _Included_com_example_helloworld_AlarmTest#ifdef __cplusplusextern "C" {#endif#undef com_example_helloworld_AlarmTest_POWER_OFF_WAKE_UP#define com_example_helloworld_AlarmTest_POWER_OFF_WAKE_UP 8L/* * Class: com_example_helloworld_AlarmTest * Method: test * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_helloworld_AlarmTest_test (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -jni com.example.helloworld error: cannot access com.example.helloworld class file for com.example.helloworld not found javadoc: error - Class com.example.helloworld not found. Error: No classes were specified on the command line. Try -help. weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$
可以看到自动生成对应的函数:Java_com_example_helloworld_AlarmTest_testJava_ + 包名(com_example_helloworld) + 类名(AlarmTest) + 接口名(test):必须要按此JNI规范来操作;
第三步
通过.h来制作.c
看看我们的.c 我们只是需要.h里面那个函数名字,.h没有被引用,也没有参与编译和预编译
helloworld.c如下:
#include#include JNIEXPORT jstring JNICALL Java_com_example_helloworld_AlarmTest_test (JNIEnv *env, jobject thiz){ return (*env)->NewStringUTF(env,"weiqifa hello for JNI");}
第四步
生成so文件
看一下我们的mk文件
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := helloWorldLOCAL_SRC_FILES := helloWorld.cinclude $(BUILD_SHARED_LIBRARY)
会生成如下的so文件:
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$ ls libhelloWorld.so weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$第五步
执行验证
直接用eclipse安装 或者用 adb push 进去 用adb的话要手动安装so 文件并且改一下权限
10-20 03:06:45.241: E/weiqifa(12194): weiqifa hello for JNI
10-20 03:06:45.241: V/ActivityThread(12194): activityCreated r=ActivityRecord{41e7a890 token=android.os.BinderProxy@41e7a060 {com.example.helloworld/com.example.helloworld.AlarmTest}}问题:
刚开始的时候,我在Android.mk里面写的LOCAL_MODULE生成的模块名称是大写W,helloWorld
LOCAL_MODULE := helloWorld
但是在android源码里面,我写的
System.loadLibrary("helloWorld");
里面的helloworld是小写w,然后运行一直加载不成功,后面有个朋友帮我看了一下,找到原因,粗心大意啊。
转载地址:https://linus.blog.csdn.net/article/details/49274581 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!