• Create Account

### #Actualtom_mai78101

Posted 08 July 2012 - 03:54 AM

Goal:

I wanted to show a dialog pop-up to the player (user), to tell them a message, such as the high score, obtaining user names, etc. for the scoreboard. Anything involving a dialog and user input, all is welcome.

Design:

I have a background rendering Canvas, displaying the basic objects on screen. And then there's the dialog. When a player meets a simple goal, the dialog should pop-up and congratulates the player for completing the goal, and then returns to the screen, where the screen itself continues to be rendering/drawing the objects onto the screen.

Problem:

When calling a dialog to show up, I do not understand why it is required to called upon Looper.prepare() and Looper.loop(). And how do you get back to the main thread, so that the dialog can be dismissed while the rendering thread continues rendering/drawing. Even more complicated is that, for a simple dialog to show up while the background rendering is drawing objects onto the screen is hard. I do not understand how to link one part of the game logic to the next one.

Source:

This entire project took months to try to get this dialog to work, yet failed. I recreated only the problems at hand and scaled it down very much, so that the same error occurs at a suitable and manageable size. Below is the rewritten work, everything else (artwork, objects, classes, etc.) is removed, so as to concentrate on the core problem.

package ff.ff;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Surface.OutOfResourcesException;
public class Basic extends Activity {
private Render view;

public class Render extends SurfaceView implements Runnable {

//TODO: Test if AlertDialog can be able to work while another
//
// Failed miserably.

/*
* 07-08 17:34:51.035: E/AndroidRuntime(7356): FATAL EXCEPTION: Thread-12
* 07-08 17:34:51.035: E/AndroidRuntime(7356): java.lang.RuntimeException: Main thread not allowed to quit
* 07-08 17:34:51.035: E/AndroidRuntime(7356):  at android.os.MessageQueue.enqueueMessage(MessageQueue.java:191)
* 07-08 17:34:51.035: E/AndroidRuntime(7356):  at android.os.Looper.quit(Looper.java:231)
* 07-08 17:34:51.035: E/AndroidRuntime(7356):  at ff.ff.Basic$Render$1$1.run(Basic.java:45) * 07-08 17:34:51.035: E/AndroidRuntime(7356): at java.lang.Thread.run(Thread.java:1027) * */ private int r, g, b; private boolean running; private SurfaceHolder holder; private AlertDialog.Builder builder; private AlertDialog dialog; public Render(Context context) { super(context); holder = this.getHolder(); r = g = b = 0; builder = new AlertDialog.Builder(context); builder.setTitle("Enter"); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.d("Render Dialog", "Working..."); Log.d("Render Dialog", "Exiting the Looper loop..."); new Thread(new Runnable(){ public void run(){ Looper.getMainLooper().quit(); //<---------------------- ERROR WHERE IT OCCURRED. } }).start(); } }); dialog = builder.create(); } public void setLoopFlag(boolean value) { running = value; } public void run() { boolean flag = false; while(running) { if (holder.getSurface().isValid()) { Canvas c = null; try { c = holder.getSurface().lockCanvas(null); } catch(IllegalArgumentException e) { e.printStackTrace(); } catch(OutOfResourcesException e) { e.printStackTrace(); } c.drawARGB(255, r, g, b); r++; g++; b++; if (r > 250 || g > 250 || b > 250) { r = 0; g = 0; b = 0; } if (!flag){ flag = true; Looper.prepare(); dialog.show(); Looper.loop(); } holder.getSurface().unlockCanvasAndPost(c); } } } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); view = new Render(this); view.setLoopFlag(true); setContentView(view); Thread thread = new Thread(view); thread.setName("Render Thread"); thread.start(); } }  Neatly packed into 1 Java class. Conclusion: I hoped this is enough information needed to solve this matter. ### #1tom_mai78101 Posted 08 July 2012 - 03:53 AM Goal: I wanted to show a dialog pop-up to the player (user), to tell them a message, such as the high score, obtaining user names, etc. for the scoreboard. Anything involving a dialog and user input, all is welcome. Design: I have a background rendering Canvas, displaying the basic objects on screen. And then there's the dialog. When a player meets a simple goal, the dialog should pop-up and congratulates the player for completing the goal, and then returns to the screen, where the screen itself continues to be rendering/drawing the objects onto the screen. Problem: When calling a dialog to show up, I do not understand why it is required to called upon Looper.prepare() and Looper.loop(). And how do you get back to the main thread, so that the dialog can be dismissed while the rendering thread continues rendering/drawing. Even more complicated is that, for a simple dialog to show up while the background rendering is drawing objects onto the screen is hard. I do not understand how to link one part of the game logic to the next one. Source: This entire project took months to try to get this dialog to work, yet failed. I recreated only the problems at hand and scaled it down very much, so that the same error occurs at a suitable and manageable size. Below is the rewritten work, everything else (artwork, objects, classes, etc.) is removed, so as to concentrate on the core problem. package ff.ff; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.Canvas; import android.os.Bundle; import android.os.Looper; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Surface.OutOfResourcesException; public class Basic extends Activity { private Render view; public class Render extends SurfaceView implements Runnable { //TODO: Test if AlertDialog can be able to work while another //thread is running continuously. // // Failed miserably. //ERROR Received: /* * 07-08 17:34:51.035: E/AndroidRuntime(7356): FATAL EXCEPTION: Thread-12 * 07-08 17:34:51.035: E/AndroidRuntime(7356): java.lang.RuntimeException: Main thread not allowed to quit * 07-08 17:34:51.035: E/AndroidRuntime(7356): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:191) * 07-08 17:34:51.035: E/AndroidRuntime(7356): at android.os.Looper.quit(Looper.java:231) * 07-08 17:34:51.035: E/AndroidRuntime(7356): at ff.ff.Basic$Render$1$1.run(Basic.java:45)
*
*/

private int r, g, b;

private boolean running;
private SurfaceHolder holder;

public Render(Context context) {
super(context);
holder = this.getHolder();
r = g = b = 0;
builder.setTitle("Enter");
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("Render Dialog", "Working...");
Log.d("Render Dialog", "Exiting the Looper loop...");
public void run(){
Looper.getMainLooper().quit();
}
}).start();
}
});
dialog = builder.create();
}

public void setLoopFlag(boolean value) {
running = value;
}

public void run() {
boolean flag = false;
while(running) {
if (holder.getSurface().isValid()) {
Canvas c = null;
try {
c = holder.getSurface().lockCanvas(null);
}
catch(IllegalArgumentException e) {
e.printStackTrace();
}
catch(OutOfResourcesException e) {
e.printStackTrace();
}
c.drawARGB(255, r, g, b);
r++;
g++;
b++;
if (r > 250 || g > 250 || b > 250) {
r = 0;
g = 0;
b = 0;
}
if (!flag){
flag = true;
Looper.prepare();
dialog.show();
Looper.loop();
}
holder.getSurface().unlockCanvasAndPost(c);
}
}
}
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new Render(this);
view.setLoopFlag(true);
setContentView(view);