【问题标题】:Why does runOnUIThread still cause looper.prepare() error message为什么runOnUIThread仍然会导致looper.prepare()错误信息
【发布时间】:2017-04-20 12:37:00
【问题描述】:

我有一个使用 Libgdx 游戏引擎的 Android 游戏。我有一个扩展 Libgdx 的 AndroidApplication 类的 Android 活动 (mAndroidLauncher)。有一种方法可以创建 Android 警报对话框:

mAndroidLauncher.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mAndroidLauncher.getContext());
        builder.setTitle("Notice");
        builder.setMessage("Alert!!!");
        builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
               //OK
            }
        });
        AlertDialog dialog = builder.create();
        dialog.show();
    }
});

我在 Google Play 开发者控制台中出现如下崩溃:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:208)
at android.os.Handler.<init>(Handler.java:122)
at android.app.Dialog.<init>(Dialog.java:109)
at android.app.AlertDialog.<init>(AlertDialog.java:114)
at android.app.AlertDialog$Builder.create(AlertDialog.java:931)
at com.google.android.gms.common.e.a(Unknown Source)
at com.google.android.gms.common.e.a(Unknown Source)
at com.my.game.l.a(Unknown Source)
at com.my.game.l.g(Unknown Source)
at com.my.game.l.c(Unknown Source)
at com.my.game.a.b(Unknown Source)
at com.my.game.b.f.a(Unknown Source)
at com.my.game.q.b(Unknown Source)
at com.badlogic.gdx.backends.android.i.onDrawFrame(Unknown Source)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1557)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1263)

这是我的应用程序中唯一使用 AlertDialog 的地方,这就是为什么我确信这是导致崩溃的方法。为什么 runOnUiThread 会导致此错误?我是否需要做任何其他事情来确保 AlertDialog 是从带有 looper 的线程构建的?

编辑:感谢 CommonsWare。该错误确实来自 Google Play 服务。具体来说,我调用了未包含在 runOnUiThread() 中的 gameHelper.beginUserInitiatedSignIn()。虽然奇怪的是,这并没有导致所有手机都出错

【问题讨论】:

  • 您显示的代码未生成此堆栈跟踪。 “这是我的应用程序中唯一使用 AlertDialog 的地方”——这不是您的 AlertDialog。它来自 Play Services。
  • 感谢您的帮助。你怎么知道它来自 Play Services?以及如何/在哪里可以找出导致错误的原因?
  • "你怎么知道它来自 Play Services?" -- 因为崩溃来自com.google.android.gms.common.e.a(),那就是播放服务。 “我如何/在哪里可以找出导致错误的原因?” -- 如果你的代码在你的堆栈跟踪中是com.my.game,使用ProGuard 映射文件找出com.my.game.l.a() 在哪里。

标签: java android libgdx android-alertdialog android-runonuithread


【解决方案1】:
 new Handler(Looper.getMainLooper()).postDelayed(new Runnable()
            {
                @Override
                public void run()
                {
                    //Do something here
                    AlertDialog.Builder builder = new AlertDialog.Builder(mAndroidLauncher.getContext());
        builder.setTitle("Notice");
        builder.setMessage("Alert!!!");
        builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
               //OK
            }
        });
        AlertDialog dialog = builder.create();
        dialog.show();
                }
            }, 0);

【讨论】:

    【解决方案2】:

    您不能像调用静态方法一样直接使用 Activity 名称调用 runOnUIThread(){}...在 mAndroidLauncher 中声明一个对象为

    public static Activity acitivity = this;
    

    并调用 runOnUIThread 为

    mAndroidLauncher.activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            AlertDialog.Builder builder = new AlertDialog.Builder(mAndroidLauncher.getContext());
            builder.setTitle("Notice");
            builder.setMessage("Alert!!!");
            builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                   //OK
                }
            });
            AlertDialog dialog = builder.create();
            dialog.show();
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2017-02-20
      • 2012-05-04
      • 2020-07-16
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多