第一次调用JNI

本文详细介绍如何通过JNI让Java调用C/C++代码,包括创建Java类声明native方法、生成并配置C/C++源文件、编译生成SO库及在Android项目中使用。

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

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

复制代码
public class printHello {

    public synchronized static native String printHello();

    static {
        System.loadLibrary("printHello");

    }

}
复制代码

 

新建一个JNI文件


Rebuil一下,出现classes文件


然后输入命令:


输入命令

cd app/build/intermediates/classes/debug

 回车后输入命令

 javah -jni (这里是报名).(上面你写的类名)

javah -jni com.example.administrator.myjni.printHello

这个时候就会在你的jni文件下生成一个文件.h

把这个文件复制到你建的jni 文件下


这个文件在build  >>classes>>目录下会生成一个.h文件

这个是生的文件

复制代码
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_administrator_myjni_printHello */

#ifndef _Included_com_example_administrator_myjni_printHello
#define _Included_com_example_administrator_myjni_printHello
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_administrator_myjni_printHello
 * Method:    printHello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_administrator_myjni_printHello_printHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
复制代码

新建一个.C文件,名字随便 

拷贝.h文件里面的内容,修改为

复制代码
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_administrator_myjni_printHello */

#ifndef _Included_com_example_administrator_myjni_printHello
#define _Included_com_example_administrator_myjni_printHello
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_administrator_myjni_printHello
 * Method:    printHello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_administrator_myjni_printHello_printHello
        (JNIEnv *env, jclass jobj){
    //返回一句话
    return (*env)->NewStringUTF(env,"JNI JAVA调用C就是这么简单");

}

#ifdef __cplusplus
}
#endif
#endif
复制代码

 

还要在jni文件夹下添加一个空白的util.c文件,不然会报错,我也不知道为什么。


 

5、配置NDK

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

    

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

  

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

 

6、生成SO库

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

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

 

7、配置so库

在src\main下新建文件夹jniLIB,并将生成的SO文件拷贝到该文件夹下

 

这个时候你可以配置

sourceSets.main {
    jni.srcDirs = []
    jniLibs.srcDir 'src/main/jniLibs'
}

配置好了后,就可以不用jni文件了

如果出现找不到文件》》要用真机调试

System.loadLibrary("Myserial");
Myserial这个要和so文件名一样 ,不一样会报错,找不到文件》》libMyserial.so
lib是自动加的,不用管


//   如果你要把OS文件打包成  jar 包 就用下面的代码
//   要把你要打包的jar放到 libs 
    task nativeLibsToJar(type: Zip, description: "create a jar archive of the native libs") {
        destinationDir file("$projectDir/libs")
        baseName "myjni"
        extension "jar"
        from fileTree(dir: "libs", include: "**/*.so")
        into "lib"
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn(nativeLibsToJar)
    }


8、使用JNI

因为native方法声明成了静态的方法,在Activity里面直接调用myJNI类就行

复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button button = (Button) findViewById(R.id.button);
    final TextView textView = (TextView) findViewById(R.id.textView);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            textView.setText(printHello.printHello() + "");//加""
        }
    });

}
}
复制代码

 

 

ok!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值