Search code examples
androidglsurfaceview

How to show UI in GLSurfaceView based game Android?


I am building a game which contains a GLSurfaceView. This GLSurfaceView receives all touch events and based on that game proceeds. Now based on certain conditions i want to show certain dialog box. Say game ends on a double tap, I want to show a dialog box saying if user wants to restart. But i guess these events are not handled in UI thread so when I am trying to create dialog box my app is crashing. How can I achieve this ?

Code which is creating this dialog:

 Context ctx = MainActivity.getContext();
 AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
            builder.setTitle(ctx.getResources().getString(R.string.ThemeSelectionDialogTitle));
            builder.setCancelable(true);
            final CharSequence[] items={"Theme 1", "Theme 2"};

            builder.setSingleChoiceItems(items,-1, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) 
                {
                    if("Theme 1".equals(items[which]))
                    {
                        Log.i(LOGUtil.LOG_TAG, "Theme 1 Selected");
                    }
                    else if("Theme 2".equals(items[which]))
                    {
                        Log.i(LOGUtil.LOG_TAG, "Theme 2 Selected");
                    }
                    dialog.dismiss();
                }
            });

            //now that the dialog is set up, it's time to show it    
            AlertDialog alertDialog = builder.create();
            alertDialog.show();

CallStack:

DalvikVM[localhost:8600] Thread [<1> main] (Suspended (exception WindowManager$BadTokenException))
ViewRootImpl.deliverInputEvent(ViewRootImpl$QueuedInputEvent) line: 5662 ViewRootImpl.doProcessInputEvents() line: 5588
ViewRootImpl.enqueueInputEvent(InputEvent, InputEventReceiver, int, boolean) line: 5559
ViewRootImpl$WindowInputEventReceiver.onInputEvent(InputEvent) line: 5737
ViewRootImpl$WindowInputEventReceiver(InputEventReceiver).dispatchInputEvent(int, InputEvent) line: 185 MessageQueue.nativePollOnce(int, int) line: not available [native method] MessageQueue.next() line: 138
Looper.loop() line: 123 ActivityThread.main(String[]) line: 5086
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] Method.invoke(Object, Object...) line: 515 ZygoteInit$MethodAndArgsCaller.run() line: 785 ZygoteInit.main(String[]) line: 601 NativeStart.main(String[]) line: not available [native method]
Thread [<10> Binder_2] (Running) Thread [<9> Binder_1] (Running) Thread [<11> GLThread 4824] (Running) Thread [<12> Binder_3] (Running)

Relevant Logcat Output:

D/SomeSDK( 3817): Game Draw !!! D/WifiStateMachine( 1068): handleMessage: E msg.what=151572 D/WifiStateMachine( 1068): processMsg: ConnectedState D/WifiStateMachine( 1068): processMsg: L2ConnectedState W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for Consumers.consumeAsync W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for Consumers.consumeAsync W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@4210c078 ... ...

D/WifiStateMachine( 1068): handleMessage: X W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@4210c078 ... ... W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for Consumers.consumeAsync W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for Consumers.consumeAsync W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@42103ca8 ... ... W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for Consumers.consumeAsync D/dalvikvm(27831): GC_CONCURRENT freed 2085K, 39% free 10594K/17184K, paused 2ms+2ms, total 26ms D/dalvikvm(27831): WAIT_FOR_CONCURRENT_GC blocked 18ms D/dalvikvm(27831): WAIT_FOR_CONCURRENT_GC blocked 18ms D/dalvikvm(27831): WAIT_FOR_CONCURRENT_GC blocked 19ms D/dalvikvm(27831): WAIT_FOR_CONCURRENT_GC blocked 19ms W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for Consumers.consumeAsync W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@420abc18 W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@420a7a80... ...

W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@4233f958 W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for Consumers.consumeAsync ... ... W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@421b6100 W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@420abc18 W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@420a7a80 W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@42099068 W/HandlerScheduledExecuto(27831): Task does not implement UiTask. Consider using NamedUiRunnable for eky@42096ed8 W


Solution

  • Use the Activity instance as your context rather than a static context, like that application context. The dialog is bound to the lifecycle of your Activity so it needs the instance rather than a static which may no longer be valid.