Java 通过NDK回调在Android中创建消息对话框
我有一个android应用程序,其中我在Java端设置了OpenGL上下文,并从NDK/C++端发送图形。这一切似乎都很有效 <>我希望C++侧能够弹出对话框。我实现了一个javaJava 通过NDK回调在Android中创建消息对话框,java,android,opengl-es,dialog,android-ndk,Java,Android,Opengl Es,Dialog,Android Ndk,我有一个android应用程序,其中我在Java端设置了OpenGL上下文,并从NDK/C++端发送图形。这一切似乎都很有效 我希望C++侧能够弹出对话框。我实现了一个javamakeadilog函数,该函数通过env->CallVoidMethod(javaClass,javaMethod)从C端被很好地激发我的Java端接收函数如下所示: public static void MakeADialog() { Log.w("title", "MakeADialog fired!"
makeadilog
函数,该函数通过env->CallVoidMethod(javaClass,javaMethod)从C端被很好地激发代码>我的Java端接收函数如下所示:
public static void MakeADialog() {
Log.w("title", "MakeADialog fired!");
}
这是一个单独的类(不是活动
或可运行
)。以上工作正常,我可以看到我的MakeADialg日志消息。然而,当我试图创建一个实际的对话框时,就会出现很多崩溃。当我从C端调用Java端时,我可以看出我并没有在摸索我正在运行的“线程”。当我尝试创建新的线程/对话框时,似乎遇到了麻烦
我在这里尝试了很多关于创建可运行线程、线程等的建议,但它们似乎总是给我一个可怕的“无法在未调用Looper.prepare()的线程内创建处理程序”或者视图的父级为空。大多数方法都是将活动和上下文指针存储为静态的,并在MakeADialog回调中通过get函数检索它们
AlertDialog-AlertDialog=new-AlertDialog.Builder(MyApp.GetMyContext()).create()
其中GetMyContext()函数只返回我在应用程序启动期间存储的主活动创建线程的指针
是否有人弹出了一个从NDK端启动的对话框,或者可以向我指出一些相关文档,帮助我了解如何从NDK回调创建新对话框
提前谢谢 也许我们可以使用中的示例创建一个模态对话框。我怀疑您是从工作线程调用它的,因此“他们似乎总是给我一个可怕的‘无法在未调用Looper.prepare()
’的线程内创建处理程序,或者视图的父线程为null。”(另请参阅)
关键代码基于官方示例和:
在爪哇方面,
包ss.fang.brickgo;
导入android.app.AlertDialog;
导入android.app.Dialog;
导入android.app.NativeActivity;
导入android.content.DialogInterface;
导入android.content.pm.ApplicationInfo;
导入android.graphics.Color;
导入android.graphics.drawable.ColorDrawable;
导入android.os.Bundle;
导入android.os.Looper;
导入android.util.Log;
导入android.view.Window;
导入android.view.WindowManager;
导入java.util.concurrent.Semaphore;
导入java.util.concurrent.AtomicInteger;
公共类GameActivity扩展了NativeActivity{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
/**
*这个函数将由C++通过名称和签名调用(Ljava/Lang/string;z)i)
*
*@param message要显示的消息文本
*@param model如果为true,它将阻止当前线程,否则,它就像一个无模式对话框。
*@为模型对话框单击的按钮的返回id,否则为0。
*@see#showAlertCallback
*@见
*@见
*/
public int showAlert(最终字符串消息,布尔模型){
//https://stackoverflow.com/questions/11411022/how-to-check-if-current-thread-is-not-main-thread
if(Looper.myLooper()==Looper.getMainLooper()&&model){
//当前线程是UI Thread.Looper.getMainLooper().isCurrentThread()
//android.os.NetworkOnMainThreadException
抛出新的RuntimeException(“无法在主线程内创建模型对话框”);
}
ApplicationInfo ApplicationInfo=getApplicationInfo();
final CharSequence appName=getPackageManager().getApplicationLabel(applicationInfo);
//使用一个信号量来创建一个模态对话框。另外,它由对话框的侦听器保存。
最终信号量信号量=模型?新信号量(0,true):null;
//单击的按钮(例如,按钮为正)或单击项目的位置
final AtomicInteger buttonId=新的AtomicInteger();
this.runOnUiThread(新的Runnable(){
公开募捐{
AlertDialog.Builder=新建AlertDialog.Builder(GameActivity.this,AlertDialog.THEME\u HOLO\u DARK);
builder.setTitle(appName);
builder.setMessage(message);
DialogInterface.OnClickListener listener=新建DialogInterface.OnClickListener(){
public void onClick(DialogInterface对话框,int-id){
按钮设置(id);
if(null!=信号量)
semaphore.release();
其他的
showAlertCallback(id);
if(DialogInterface.BUTTON_正数==id){
GameActivity.this.finish();
}
}
};
setNegativeButton(android.R.string.cancel,listener);
setPositiveButton(android.R.string.ok,listener);
builder.setCancelable(false);
AlertDialog=builder.create();
dialog.show();
}
});
if(null!=信号量)
试一试{
semaphore.acquire();
}捕捉(中断异常e){
Log.v(“游戏活动”,“忽略”,e);
}
return buttonId.get();
}
/**
*showAlert的回调,其行为类似于无模式对话框
*
*@param id单击的按钮
*/
公共本机void showartcallback(int-id);
/**
*@见
*/
受保护的void showDialog(){
Dialog=新建对话框(此对话框);
dialog.getWindow().requestFeature(Window.FE