安卓JNI动态注册
在安卓JNI静态注册一文中我提到要使用c/c++代码中的方法,就需要在android代码中对c/c++代码中的方法进行注册,注册方式有两种: 静态注册和动态注册,本文讲的是JNI动态注册
为什么有静态注册和动态注册之分,本文不讨论,本文送上的是如何实现的干货。
一,AS新建一个Native C++项目。好处是无需你配置JNI环境。

创建好空项目后会提示你没有在AS中配置NDK路径,如下图:

此时我们可以点击右上角的Project Structure按钮,在弹出的窗口中配置Android NDK location,即可,例如我这儿是如下图所示:

Apply->Ok后就配置完成了。
二,随手布局和写几句java代码。
我这里布局只布局一个按钮,要实现的功能是点击按钮时通过jni动态注册的方式调用c++代码中的方法并获取返回内容最后弹窗显示返回内容。

编写java代码,实现按钮点击事件
注意,如果有人尝试一步一步按照本文来操作的话,那么默认空项目里的hello,world的textview控件需要删除,自然而然MainActivity里就获取不到该控件了,对应的代码也需要删除

删除后开始写自己的代码,我们布局的是一个按钮控件,功能是点击按钮时通过jni动态注册的方式调用c++代码中的方法并获取返回内容最后弹窗显示返回内容。
java代码如下:
package com.example.dynamicregister; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; 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); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String result = stringFromJNI(); Toast.makeText(getApplicationContext(),result,Toast.LENGTH_LONG).show(); } }); } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNI(); }
三,开始编写JNI动态注册代码
由于AS已经帮我在java代码中自动写了System.loadLibrary和native声明的stringFromJNI方法,当然你也可以自己修改loadLibrary的库名称和stringFromJNI方法名称,但不是仅仅改java代码中的名称就完事儿,所以不清楚的话请不要去改。
基于上面的步骤都OK了之后,我们进入CPP目录,编辑native-lib.cpp文件,代码如下:
#include <jni.h> //1,实现对应的方法 jstring stringFromJNI(JNIEnv *env, jobject){ return env->NewStringUTF("Hi,我是JNI动态注册"); } //2,注册对应的方法 JNINativeMethod methods[] = { {"stringFromJNI","()Ljava/lang/String;",(jstring *)stringFromJNI} }; //3,使用JNI_OnLoad载入对应的方法 jint JNI_OnLoad(JavaVM *vm, void *unused) { JNIEnv *env; if(vm->GetEnv((void **) &env,JNI_VERSION_1_6) != JNI_OK)return JNI_ERR; jclass jc = env->FindClass("com/example/dynamicregister/MainActivity"); env->RegisterNatives(jc,methods,sizeof(methods)/ sizeof(methods[0])); return JNI_VERSION_1_6; }
大致总结起来就是三步走:
1,实现对应的方法
2,注册对应的方法
3,使用JNI_OnLoad载入对应的方法
四,点击AS右上角的绿色三角按钮,AS会自动编译so文件,自动打开模拟器自动安装app运行,第一次由于需要初始化AS的模拟器会需要点儿时间。
运行的效果如下图:
