android的JNI学习笔记

1、百度,找到最简单的学习资料,要类似hello world这样的,否则事倍功半,切记!!!

2、还真找到了hello, ^_^

3、

新建一个类,声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。

不在Activity类里面写是为了避免编译时报错:找不到android.support.v7.app.AppCompatActivity

public class myJNI {

  //加载so库
    static {
        System.loadLibrary("JniTest");
    }

  //native方法
    public static native String sayHello();

}

4、上一步基本不会有错,且看这一步:打开android studio终端,使用javac编译上述文件,生成class文件。

命令:

D:\AndroidStudioProject\testJNI\app\src\main\java\com\example\binbin\testjni>javac myJNI.java

注:这一步就有两问题,首先,要用CD命令(跟DOS命令一个意思)进入到前面所建的类的那个目录。

其次 很容易出现  错误: 编码GBK的不可映射字符,这时就要对javac 命令加参数,变成如下:

javac -encoding UTF-8 myJNI.java

OK,这下不报错了,通过,你会发现那目录下多了一个myJNI.class的文件

5、确认自己类的包名!然后在上一级的位置使用javah生成.h头文件

一定要在上一级哦,不然不会报错:找不到xxx类

这里一定要注意,要用CD..  命令往回走到包的起始目录,比如我这里就要回到D:\AndroidStudioProject\testJNI\app\src\main\java  目录下,然后执行javah 命令,包名是放在参数中了

D:\AndroidStudioProject\testJNI\app\src\main\java>javah -jni com.example.binbin.testjni.myJNI

OK,现在在java目录下生成了一个   .h 文件,文件名有点长。

第4步是javac, 第5步是javah

6、在java目录下新建目录:jni, 在这新目录下新建main.c文件,同时把上一步生成的.h文件中的内容复制到此文件中

注:这里新建的时候,不要建成c/c++ class, 而是要选c/c++ source file ,开始没留意,死也建不成功。

原.h文件内容:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_binbin_testjni_myJNI */

#ifndef _Included_com_example_binbin_testjni_myJNI
#define _Included_com_example_binbin_testjni_myJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_binbin_testjni_myJNI
 * Method:    sayHello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_binbin_testjni_myJNI_sayHello
        (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

复制,并修改后的main.c中的代码,就增加了一行 return :

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_binbin_testjni_myJNI */

#ifndef _Included_com_example_binbin_testjni_myJNI
#define _Included_com_example_binbin_testjni_myJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_binbin_testjni_myJNI
 * Method:    sayHello
 * Signature: ()Ljava/lang/String;
 */

//就实现了个函数 JNIEnv的用法可以自行百度,这里就不展开了
JNIEXPORT jstring JNICALL Java_com_example_binbin_testjni_myJNI_sayHello
        (JNIEnv *env, jclass jobj){

  //返回一句话
    return (*env)->NewStringUTF(env,"JNI hahahahahahahaha");

}

#ifdef __cplusplus
}
#endif
#endif

7、据说还要jni目录下增加一个util.c的文件,否则会报错,暂不管,等看到报错再说,否则都不知有什么错,不利于学习^_^

8、配置NDK

打开Project的local.properties文件添加NDK路径

到了这里才发现没有NDK,不要紧,按下面的链接,两三分钟就下好了,现在对谷歌的下载界面已经没有屏蔽了,要是几年前,光下这个,估计就不知要到什么时候去了,当然那里网速也慢。^_^

https://dl.google.com/android/repository/android-ndk-r19c-windows-x86_64.zip

 

打开app Module的build.gradle文件,在defaultConfig节点里添加以下代码
注意这里的moduleName,是我们在之前自己编写的类里面加载的so库名
ndk {
            moduleName "JniTest"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }

这里有个坑的地方是,build.gradle文件不要找错一个了,否则没地方加这一小段,

另外 abiFilters "armeabi", "armeabi-v7a", "x86" 这个好象是指要匹配的CPU类型??

还要在gradle.properties里面加上这么一句话:android.useDeprecatedNdk=true

配置完成

9、生成SO库

完成以上步骤之后,我们rebuild一下就可以生成so库了

在项目的app\build\intermediates\ndk\debug\lib路径下

这一步,死活成功不了,在这intermediates目录下,找不着ndk目录,我倒。。。。然后jniLibs下也没有东西

再百度,发现还需要在build.gradle中增加

sourceSets{
    main{
        jniLibs.srcDir 'src/main/java/jni'//告知jni源码目录
    }
}

追加在NDK配置时,那一段NDK的后面即可

但是这到,仍然没有生成SO文件

已经好晚了,先到这儿,改天继续研究,暂时判断的错误是前文关于NDK的配置是有问题的,android.useDeprecatedNdk要取消了:

Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章