Android:JNI 动态注册和静态注册的详解
一、JNI是什么?
JNI是Java Native Interface的缩写,中文名为JAVA本地调用。它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。Java是支持调用C/C++代码的,不过不能直接调用,因此需要一个中间层来进行转换、翻译,这就是JNI(Java Native Interface)的意思,JNI的作用就是粘合Java代码和C++代码。
二、JNI注册方法
静态注册和动态注册。区别是效率。静态注册,每次使用native方法时,都要去寻找;而动态注册,由于有张表的存在,因此查找效率高。静态注册多用于NDK开发,而动态注册多用于Framework开发。不管是静态注册方法,还是动态注册方法,都需要将c文件编译成平台所需要的库。
三、静态注册
3.1静态注册原理:根据函数名来建立 java 方法与 JNI 函数的一一对应关系;在Java虚拟机加载so库时,如果发现含有上面两个宏定义的函数时就会链接到对应Java层的native方法,那么怎么知道对应Java中的哪个类的哪个native方法呢,我们仔细观察JNI函数名的构成其实是:以Java为前缀,并且用“_”下划线将包名、类名以及native方法名连接起来就是对应的JNI函数了。
其实就是:Java+包名+类名+方法名(native方法)
例如:Java_packagename_classname_methodname(JNIEnv *env,jclass/jobject,...)
3.2 静态注册方法步骤
1,在Java文件中定义native方法。
2,在cmd命令行模式中切换目录到定义native方法class文件(或者java文件)存放位置。
3,用javah 和javac命令生成包含native方法的.h头文件。
4,实现native方法,用ndk-build编译生成.so库。
3.3静态方法注册JNI的弊端
- 必须遵循某些规则
- 名字过长
- 多个class需Javah多遍,其实Android Studio中可不用这么做
- 运行时去找效率不高
例子:
package com.example.client.jnitest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
final TextView tv = findViewById(R.id.sample_text);
Button testBt = findViewById(R.id.test_bt)<