当前位置:   article > 正文

Android JNI 开启子线程后调用 Activity 方法更新UI_jni调用mainactivity

jni调用mainactivity
  • MainActivity 代码
    点击按钮调用 native 方法,开启线程,调用MainActivity 方法更新UI
class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG: String = "MainActivity";

        init {
            System.loadLibrary("native-lib")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    }

    fun onClick(view: View) {
        useThread()
    }

    private external fun useThread();

    // AndroidUI操作,让C++线程里面来调用
    fun updateUI() {
        if (Looper.getMainLooper() == Looper.myLooper()) {
            showDialog()
        } else {
            Log.d("MainActivity", Thread.currentThread().name)
            runOnUiThread {
                showDialog();
            }
        }
    }

    private fun showDialog() {
        AlertDialog.Builder(this@MainActivity)
            .setTitle("hello!!!")
            .setMessage("updateUI run ...")
            .setPositiveButton("确定", null)
            .show()
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • native 方法 具体作用都在注释里面了
#include <jni.h>
#include <string>
#include <android/log.h>
#include <pthread.h>

#define TAG "ld"
#define log_debug(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)
#define log_info(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)

jobject mainActivityObj;
JavaVM *jvm;

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *javaVm, void *pVoid) {
    // 获取 javaVM
    jvm = javaVm;
    return JNI_VERSION_1_6;
}

void *customerThread(void *pVoid) {
    // JVM 是可以跨线程使用的
    // JNIEnv是不可以跨线程的 所以需要通过 JVM创建当前线程使用的 JNIEnv
    JNIEnv *env = nullptr;
    jint result = jvm->AttachCurrentThread(&env, 0);
    log_debug("创建env结果为:%d", result);
    if (result != JNI_OK) {
        return 0;
    }
    // 获取 MainActivity 的 jclass
    jclass mainActivityClass = env->GetObjectClass(mainActivityObj);
    const char *sig = "()V";
    jmethodID mainMethodId = env->GetMethodID(mainActivityClass, "updateUI", sig);
    // 调用 updateUI 方法
    env->CallVoidMethod(mainActivityObj, mainMethodId);
    // 解除线程 释放挂在 JVM的native线程
    jvm->DetachCurrentThread();
    return 0;
};

// 入口
extern "C"
JNIEXPORT void JNICALL
Java_com_lu_jni_MainActivity_useThread(JNIEnv *env, jobject thiz) {
    // 必须创建一个 全局变量 来公用参数 如果是局部变量方法出栈后 对象将被释放
    mainActivityObj = env->NewGlobalRef(thiz);
    // 定义 pthread_t 线程标识
    pthread_t pthreadID;
    // 创建线程  调用 customerThread 
    pthread_create(&pthreadID, 0, customerThread, mainActivityObj);
    // 用来等待一个线程的结束,线程间同步的操作
    pthread_join(pthreadID, 0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/133166
推荐阅读
相关标签
  

闽ICP备14008679号