JNI调用Java弹出Android对话框并回传用户选择结果的实现问题
问题根源
Android 系统的AlertDialog.show()是异步执行逻辑,调用后不会阻塞当前线程等待用户操作,会直接继续执行后续代码,所以你现有的同步调用逻辑无法拿到用户的选择结果。
实现方案
这里提供两种可行方案,你可以根据自己的业务场景选择:
方案1:同步阻塞返回(适配你现有JNI调用逻辑,改动最小)
前置要求
JNI层调用GetOption()的线程必须是非主线程,否则会阻塞主线程触发ANR,对话框也无法正常显示。
Java侧代码修改
public class appJNI extends Activity { // 存储选择结果 private Short selectResult = null; // 同步锁对象 private final Object dialogLock = new Object(); // 注意方法签名要和JNI层查找的`()S`完全对齐,不要多余参数 private short getSelectedOption() { // 对话框必须在主线程弹出,所以先post到主线程执行 runOnUiThread(() -> { AlertDialog alertDialog = new AlertDialog.Builder(appJNI.this).create(); alertDialog.setTitle("Title"); alertDialog.setMessage("What is your option?"); // 禁止点击对话框外部关闭,避免无限等待 alertDialog.setCancelable(false); // 第一个选项 alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "选项1", (dialog, which) -> { dialog.dismiss(); synchronized (dialogLock) { selectResult = 1; // 唤醒等待的线程 dialogLock.notifyAll(); } }); // 第二个选项 alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "选项2", (dialog, which) -> { dialog.dismiss(); synchronized (dialogLock) { selectResult = 2; dialogLock.notifyAll(); } }); alertDialog.show(); }); // 阻塞当前调用线程,等待用户选择完成 synchronized (dialogLock) { while (selectResult == null) { try { dialogLock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // 线程被中断返回错误码 return -1; } } short result = selectResult; // 重置状态,方便下次调用 selectResult = null; return result; } } }
JNI侧代码修改
你原有JNI代码不需要大改,只需要确认GetMethodID查找的方法签名()S和Java侧方法完全匹配即可。
方案2:异步回调(无阻塞,更灵活)
如果你的JNI调用线程不能被阻塞,可以选择JNI被动接收回调的方案:
1. Java侧新增native回调方法
// 声明native回调方法,用户选择后调用该方法通知JNI层 public native void onOptionSelected(short result);
2. 对话框点击逻辑里触发回调
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "选项1", (dialog, which) -> { dialog.dismiss(); onOptionSelected((short)1); }); alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "选项2", (dialog, which) -> { dialog.dismiss(); onOptionSelected((short)2); });
3. JNI侧实现回调方法
JNIEXPORT void JNICALL Java_com_myapp_main_appJNI_onOptionSelected(JNIEnv *env, jobject thiz, jshort result) { // 这里直接拿到用户选择的result,处理后续逻辑即可 // your logic here }
这种方案不需要JNI侧主动同步调用拿结果,也不存在线程阻塞问题,更推荐用于主线程调用的场景。
内容的提问来源于stack exchange,提问作者Palantiir
相关产品推荐
相关产品推荐

