// 1 静态注册 native 函数
public native void staticRegister();
// ---------------------------静态注册---------------------------------
extern "C"
JNIEXPORT void JNICALL
Java_com_cn_mynativestudy_MainActivity2_staticRegister(JNIEnv *env, jobject thiz) {
// 静态注册: 优点:开发简单
// 缺点
// 1.JNI函数名非常长
// 2.捆绑 上层 包名 + 类名
// 3.运行期 才会去 匹配JNI函数,性能上 低于 动态注册
LOGI("我是静态注册的函数 Java_com_cn_mynativestudy_MainActivity2_staticRegister...");
}
// ---------------------------静态注册---------------------------------
public void test01(View view) {
staticRegister();
}
// 2 动态注册 native 函数
public native void dynamicRegister();
public native int dynamicRegister2(String valueStr);
// ---------------------------动态注册----------------------------------
JavaVM *jvm = nullptr; // 定义一个 局部变量 jvm 并赋null
void jni_dynamicRegister(JNIEnv *env, jobject thiz){
LOGI("我是动态注册的函数 dynamicMethod01...");
}
int jni_dynamicRegister2(JNIEnv *env, jobject thiz, jstring value_str){
char * str = const_cast<char *>(env->GetStringUTFChars(value_str, NULL));
LOGI("我是动态注册的函数 dynamicMethod01...%s",str);
env->ReleaseStringUTFChars(value_str,str);
return 100 ;
}
JNINativeMethod jniNativeMethod[] = {
{"dynamicRegister","()V",(void *)(jni_dynamicRegister)},
{"dynamicRegister2","(Ljava/lang/String;)I",(int *)(jni_dynamicRegister2)}
};
// 类似 java 的构造函数 ,C++ 初始化时 static { System.loadLibrary("native-lib"); } 调用 JNI_OnLoad方法
extern "C"
JNIEXPORT jint JNI_OnLoad(JavaVM * javaVm ,void *){
::jvm = javaVm ;// 赋值,获取进程唯一 javaVM对象
JNIEnv *jnienv = nullptr;// 声明一个当前jnienv ;
// 通过 javavm 获取 jnienv 并赋值 ,返回 0 为成功
int result = javaVm->GetEnv(reinterpret_cast<void **>(&jnienv), JNI_VERSION_1_6);
if(result != JNI_OK){
return -1 ;
}
// 获取 activity class 对象
jclass main2_class = jnienv->FindClass("com/cn/mynativestudy/MainActivity2");
jnienv->RegisterNatives(main2_class,jniNativeMethod,
sizeof(jniNativeMethod)/sizeof(JNINativeMethod));
return JNI_VERSION_1_6; // // AS的JDK在JNI默认最高1.6
}
// ---------------------------动态注册----------------------------------
public void test02(View view) {
dynamicRegister();
}
public void test03(View view) {
int string_valueStr = dynamicRegister2("String valueStr");
Log.i("info",string_valueStr+"");
}
/** log打印
* 我是静态注册的函数 Java_com_cn_mynativestudy_MainActivity2_staticRegister...
* 我是动态注册的函数 dynamicMethod01...
* 我是动态注册的函数 dynamicMethod01...String valueStr
* 100
*/
// 3JNI 线程 实例
public native void naitveThread(); // Java层 调用 Native层 的函数,完成JNI线程
public native void closeThread(); // 释放全局引用
// ---------------------------JNI 线程----------------------------------
// JNIEnv 线程绑定 不能跨线程
// jobject 线程绑定 不能跨线程
class MyContext{
public:
JNIEnv * jniEnv = nullptr;
jobject j_obj = nullptr;
};
void * runTask(void *pVoid){
MyContext * myContext = static_cast<MyContext *>(pVoid);
// 全新的JNIEnv 异步线程里面操作
JNIEnv *jniEnv = nullptr;
// 附加当前异步线程后,会得到一个全新的 env,此env相当于是子线程专用env
jint attachResult = ::jvm->AttachCurrentThread(&jniEnv, nullptr);
if (attachResult != JNI_OK) {
return 0; // 附加失败,返回了
}
// 1.拿到class
jclass mainActivityClass = jniEnv->GetObjectClass(myContext->j_obj);
// 2.拿到方法
jmethodID updateActivityUI = jniEnv->GetMethodID(mainActivityClass, "updateActivityUI", "()V");
// 3.调用
jniEnv->CallVoidMethod(myContext->j_obj, updateActivityUI);
::jvm->DetachCurrentThread(); // 必须解除附加,否则报错
return nullptr;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_cn_mynativestudy_MainActivity2_naitveThread(JNIEnv *env, jobject thiz) {
MyContext * myContext = new MyContext();
myContext->jniEnv = env ;
myContext->j_obj = env->NewGlobalRef(thiz);//提升成全局变量;
pthread_t pid ;
pthread_create(&pid, nullptr, runTask, myContext);
pthread_join(pid, nullptr);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_cn_mynativestudy_MainActivity2_closeThread(JNIEnv *env, jobject thiz) {
}
// ---------------------------JNI 线程----------------------------------
public void test04(View view) {
naitveThread();
}
/**
* TODO 下面是 被native代码调用的 Java方法
* 第二部分 JNI线程
*/
public void updateActivityUI() {
if (Looper.getMainLooper() == Looper.myLooper()) { // TODO C++ 用主线程调用到此函数 ----> 主线程
new AlertDialog.Builder(MainActivity2.this)
.setTitle("UI")
.setMessage("updateActivityUI Activity UI ...")
.setPositiveButton("知道了", null)
.show();
} else { // TODO C++ 用异步线程调用到此函数 ----> 异步线程
Log.i("info", "updateActivityUI 所属于子线程,只能打印日志了..");
runOnUiThread(new Runnable() { // 哪怕是异步线程 UI操作 正常下去 runOnUiThread
@Override
public void run() {
// 可以在子线程里面 操作UI
new AlertDialog.Builder(MainActivity2.this)
.setTitle("updateActivityUI")
.setMessage("所属于子线程,只能打印日志了..")
.setPositiveButton("知道了", null)
.show();
}
});
}
}
版权声明:本文为a136447572原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。