Android JNI 开启子线程后调用 Activity 方法更新UI
16lz
2021-01-23
- 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() }}
- native 方法 具体作用都在注释里面了
#include #include #include #include #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 JNICALLJava_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);}
更多相关文章
- Android多线程
- Android屏幕旋转时Activity不重新调用onCreate的方法
- Android启动各种系统服务线程
- Android Studio中隐藏状态栏和标题栏的方法
- android中的短信操作