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.solib是自动加的,不用管
// 如果你要把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!
本文详细介绍如何通过JNI让Java调用C/C++代码,包括创建Java类声明native方法、生成并配置C/C++源文件、编译生成SO库及在Android项目中使用。

1030

被折叠的 条评论
为什么被折叠?



