public static void MakeADialog() {
Log.w("title", "MakeADialog fired!");
}
这是在一个单独的类中(不是activity
或runnable
)。上面的工作很好,我可以看到我的MakeADialg日志消息。然而,当我试图创建一个实际的对话框,然后我得到很多崩溃。当我从C端调用到Java端时,我可以看出我并不是在摸索我在运行什么‘线程’。当我试图创建一个新的线程/对话框时,似乎遇到了麻烦。
我已经尝试了很多关于创建Runnable线程等的建议--但它们似乎总是给我一个可怕的‘无法在未调用looper.prepare()的线程内部创建处理程序’或视图的父级为null。这些方法大多围绕将活动和上下文指针存储为静态指针,并在MakeADialog回调时通过get函数检索它们。
alertDialog alertDialog=new alertDialog.builder(myApp.GetMyContext()).create();
,其中GetMyContext()函数只返回我在应用程序启动期间存储的主活动创建线程的this
指针。
有没有人弹出了一个从他们的NDK端启动的对话框,或者可以指向我一些相关的文档,这些文档将帮助我理解如何从NDK回调创建一个新的对话框?
提前道谢!
也许我们可以使用gist中的示例来创建一个模态对话框。我怀疑您是从工作线程调用它的,所以“他们似乎总是给我可怕的‘无法在未调用looper.prepare()
的线程内部创建处理程序',或者父视图为空。”(另请参见无法在未调用looper.prepare()的线程内部创建处理程序)。
基于官方示例本机活动的关键代码和要旨代码:
package ss.fang.brickgo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NativeActivity;
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
public class GameActivity extends NativeActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* This function will be called from C++ by name and signature (Ljava/lang/String;Z)I)
*
* @param message the message text to show
* @param model if true, it will block the current thread, otherwise, it acts like a modeless dialog.
* @return return id of the button that was clicked for a model dialog, otherwise, 0.
* @see #showAlertCallback
* @see <a href="https://stackoverflow.com/questions/11730001/create-a-message-dialog-in-android-via-ndk-callback/60611870#60611870">
* Create a message dialog in Android via NDK callback</a>
* @see <a href="https://stackoverflow.com/questions/6120567/android-how-to-get-a-modal-dialog-or-similar-modal-behavior">
* Android: How to get a modal dialog or similar modal behavior?</a>
*/
public int showAlert(final String message, boolean model) {
//https://stackoverflow.com/questions/11411022/how-to-check-if-current-thread-is-not-main-thread
if (Looper.myLooper() == Looper.getMainLooper() && model) {
// Current Thread is UI Thread. Looper.getMainLooper().isCurrentThread()
//android.os.NetworkOnMainThreadException
throw new RuntimeException("Can't create a model dialog inside Main thread");
}
ApplicationInfo applicationInfo = getApplicationInfo();
final CharSequence appName = getPackageManager().getApplicationLabel(applicationInfo);
// Use a semaphore to create a modal dialog. Also, it's holden by the dialog's listener.
final Semaphore semaphore = model ? new Semaphore(0, true) : null;
// The button that was clicked (ex. BUTTON_POSITIVE) or the position of the item clicked
final AtomicInteger buttonId = new AtomicInteger();
this.runOnUiThread(new Runnable() {
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(GameActivity.this, AlertDialog.THEME_HOLO_DARK);
builder.setTitle(appName);
builder.setMessage(message);
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
buttonId.set(id);
if (null != semaphore)
semaphore.release();
else
showAlertCallback(id);
if (DialogInterface.BUTTON_POSITIVE == id) {
GameActivity.this.finish();
}
}
};
builder.setNegativeButton(android.R.string.cancel, listener);
builder.setPositiveButton(android.R.string.ok, listener);
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
}
});
if (null != semaphore)
try {
semaphore.acquire();
} catch (InterruptedException e) {
Log.v("GameActivity", "ignored", e);
}
return buttonId.get();
}
/**
* The callback for showAlert when it acts like a modeless dialog
*
* @param id the button that was clicked
*/
public native void showAlertCallback(int id);
/**
* @see <a href="https://stackoverflow.com/questions/13822842/dialogfragment-with-clear-background-not-dimmed">
* DialogFragment with clear background (not dimmed)</a>
*/
protected void showDialog() {
Dialog dialog = new Dialog(this);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// layout to display
dialog.setContentView(R.layout.dialog_layout);
// set color transpartent
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
}
}
/** @param onClickListener MUST be NULL because the model dialog is not implemented. */
typedef void *(OnClickListener)(int id);
jint showAlert(struct android_app *state, const char *message, bool model = false);
/** Process the next input event. */
static int32_t engine_handle_input(struct android_app *app, AInputEvent *event) {
auto *engine = (struct engine *) app->userData;
auto type = AInputEvent_getType(event);
if (AINPUT_EVENT_TYPE_MOTION == type) {
engine->animating = 1;
engine->state.x = AMotionEvent_getX(event, 0);
engine->state.y = AMotionEvent_getY(event, 0);
return 1;
} else if (AINPUT_EVENT_TYPE_KEY == type) {
auto action = AKeyEvent_getAction(event);
if (AKEY_EVENT_ACTION_DOWN == action && AKEYCODE_BACK == AKeyEvent_getKeyCode(event)) {
//https://stackoverflow.com/questions/15913080/crash-when-closing-soft-keyboard-while-using-native-activity
// skip predispatch (all it does is send to the IME)
//if (!AInputQueue_preDispatchEvent(app->inputQueue, event))
//int32_t handled = 0;
//if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
//AInputQueue_finishEvent(app->inputQueue, event, handled);
LOGI("Before showAlert in modal behavior, it blocks until the dialog dismisses.");
showAlert(app, "Go Back?", true);
LOGI("After showAlert in modal behavior, the dialog should have been dismissed.");
return 1;
}
}
return 0; //not handled
}
/** @return the id of the button clicked if model is true, or 0 */
jint showAlert(struct android_app *state, const char *message, bool model /* = false */) {
JNIEnv *jni = NULL;
state->activity->vm->AttachCurrentThread(&jni, NULL);
jclass clazz = jni->GetObjectClass(state->activity->clazz);
// Get the ID of the method we want to call
// This must match the name and signature from the Java side Signature has to match java
// implementation (second string hints a java string parameter)
jmethodID methodID = jni->GetMethodID(clazz, "showAlert", "(Ljava/lang/String;Z)I");
// Strings passed to the function need to be converted to a java string object
jstring jmessage = jni->NewStringUTF(message);
jint result = jni->CallIntMethod(state->activity->clazz, methodID, jmessage, model);
// Remember to clean up passed values
jni->DeleteLocalRef(jmessage);
state->activity->vm->DetachCurrentThread();
return result;
}
extern "C"
JNIEXPORT void JNICALL
Java_ss_fang_brickgo_GameActivity_showAlertCallback(JNIEnv *env, jobject thiz, jint id) {
LOGI("showAlertCallback %d", id);
}
问题内容: 我希望对话框中的消息文本居中对齐。 问题答案: 创建您自己的TextView对象,然后将其作为View提供给弹出窗口生成器: 您可以控制所有其他文本参数(样式,颜色,大小…)。要控制边距,您可以以编程方式创建LinearLayout,设置LayoutParams,然后将TextView放入其中。
问题内容: 我的应用程序显示了许多自定义对话框,例如“是/否”或“接受/取消决定”,并且在编写代码时,我意识到遵循相同的模式重复了太多代码。 我想建立一个通用类,但我不知道该怎么做,或更确切地说,我不知道该怎么做(接口,抽象类,继承,静态类等)。 这是我目前的课程: } 这就是我需要使用此类时要做的事情: 我敢肯定它是可改进的,但是您怎么能做到呢? 谢谢 问题答案: 首先创建一个Base 来保持的
问题内容: 我是android开发的新手。我想在我的应用程序中使用开发一个。当我单击“搜索”按钮时,应当与一起出现,表明在切换到另一个按钮之前进度一直在进行。请给我推荐示例代码。 问题答案: 使用。不过,您应该在new上进行工作,并在完成时使用a 回调到。这是我的方法:
我正在尝试使用随ndk提供的ndk-stack命令。 不幸的是,当我运行它时,脚本崩溃了。 我在windows上运行的命令是... ndk-stack . cmd-sym build/intermediates/cmake/debug/obj/armea bi-v7a-dump stack . txt stack.txt文件包含来自logcat的逻辑删除。 我收到的错误是.... 回溯(最后一次调
本文向大家介绍Android中创建对话框(确定取消对话框、单选对话框、多选对话框)实例代码,包括了Android中创建对话框(确定取消对话框、单选对话框、多选对话框)实例代码的使用技巧和注意事项,需要的朋友参考一下 Android中可以创建三种对话框、确定取消对话框、单选对话框、多选对话框 android中的确定取消对话框演示示例 Android中使用单选对话框的演示案例 android中使用多选
我想创建一个如下所示的自定义对话框 我试过以下几件事。 > 我创建了AlertDialog.Builder的子类,并使用了自定义标题和自定义内容视图,但结果不是预期的。 另一个尝试是子类DialogFragment并自定义onCreateDialog中的对话框,但结果并不像预期的那样。 然后我尝试使用一个普通的对话框类。结果不如预期。 在这三种情况下,问题是当我忽略标题视图时,对话框的大小不像预期