0

I have an Android game that uses the Libgdx game engine. I have an Android activity (mAndroidLauncher) that extends Libgdx's AndroidApplication class. There is a method that creates an Android alert dialog:

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();
    }
});

I have a crash in the Google Play Developer Console as follows:

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)

This is the only place in my app that I use an AlertDialog, that is why I am confident that this is the method that is causing the crash. Why would runOnUiThread cause this error? Do I need to do anything else to make sure the AlertDialog is built from a thread with a looper?

EDIT: Thanks CommonsWare. The error is indeed coming from Google Play Services. Specifically I had a call to gameHelper.beginUserInitiatedSignIn() which was not wrapped in runOnUiThread(). Although, strangely, this didn't cause an error for all phones

mrleeboze
  • 51
  • 4
  • 3
    The code you show did not generate this stack trace. "This is the only place in my app that I use an AlertDialog" -- it is not your `AlertDialog`. It is one from Play Services. – CommonsWare Dec 06 '16 at 00:25
  • Thank you for your help. How do you know it is from Play Services? And how/where can I find out what is causing the error? – mrleeboze Dec 06 '16 at 00:31
  • 2
    "How do you know it is from Play Services?" -- because the crash is coming from `com.google.android.gms.common.e.a()`, and that is Play Services. "And how/where can I find out what is causing the error?" -- if your code, in your stack trace, is `com.my.game`, use ProGuard mapping files to figure out where `com.my.game.l.a()` is. – CommonsWare Dec 06 '16 at 00:42

2 Answers2

0
 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);
Surya Prakash Kushawah
  • 3,185
  • 1
  • 22
  • 42
0

you cannot call runOnUIThread(){} directly using Activity name like calling static method...declare one object in mAndroidLauncher as

public static Activity acitivity = this;

and call runOnUIThread as

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();
    }
});
MartinTeeVarga
  • 10,478
  • 12
  • 61
  • 98