JNI 和取消 AsyncTask

3
我有一个AsyncTask,在doInBackground()里调用了一个执行一段时间的C函数。当我通过调用cancel(true)取消我的AsyncTask时,它返回true——就像任务已经终止了一样,然而在“终止”后我仍然可以看到来自C代码的日志记录。
对我来说,似乎C函数并没有真正地终止。
我的问题是——如何正确地终止执行C函数?
2个回答

3

在这里找到了答案

以下是C语言版本:

jclass thread = (*env)->FindClass(env, "java/lang/Thread");
jmethodID mCurThread = (*env)->GetStaticMethodID(env, thread, "currentThread", "()Ljava/lang/Thread;");
jmethodID mIsInterrupted = (*env)->GetMethodID(env, thread, "isInterrupted", "()Z");
jobject curThread = (jobject)(*env)->CallStaticObjectMethod(env, thread, mCurThread);

for (;;) {
    // do some stuff
    jboolean res = (jboolean)(*env)->CallBooleanMethod(env, curThread, mIsInterrupted);
    if (res == JNI_TRUE) {
        LOGI("INTERRUPTED");
    } else {
        LOGI("WORKING");
    }
}

别忘了在使用完 curThreadthread 后调用 (*env)->DeleteLocalRef(env,..),否则你将看到 PSS 不断增长的内存泄漏问题。 - ymonad

1
当AsyncTask被终止时,运行C函数的线程会被中断。您需要注意长时间运行的C代码中的中断状态(检查isInterrupted?)并手动退出。
编辑:
请查看xuggle(ffmpeg JNI包装器),特别是csrc/com/xuggle/ferry/JNIHelper.cpp,其中提供了完整且精美实现的解决方案。

你能举个调用isInterrupted的例子吗? - lstipakov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接