【发布时间】:2014-04-26 22:36:06
【问题描述】:
我想在用户完成游戏时弹出一个对话框来显示他的积分和时间。
我阅读了有关runOnUiThread 的信息,并尝试在我的代码中实现该解决方案,但无法正常工作。我收到以下错误:
"无法在未调用的线程内创建处理程序 Looper.prepare()"
.
我的SurfaceView 类中有一个名为gameCompleted 的布尔变量,当它变为真时,我调用在Activity 类中实现的方法showDialogGameCompleted()。我哪里错了?
我的活动课:
public class Canvastutorial extends Activity {
final Context context = this;
Dialog dialog;
/** Called when the activity is first created. */
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_layout);
}
// THE METHOD I CALL FROM MY SURFACEVIEW CLASS IN ORDER TO SHOW THE DIALOG
public void showDialogGameCompleted()
{
dialog= new Dialog(context);
dialog.setContentView(R.layout.custom);
dialog.setTitle("PUZZLE COMPLETED!");
// set the custom dialog components - text, image and button
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Congratulations!\nPoints: \nMoves: \nTime: ");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.cup);
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
Canvastutorial.this.runOnUiThread(new Runnable() {
public void run() {
dialog.show();
}
});
}
我的 SurfaceView 类:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private CanvasThread canvasthread;
private Canvastutorial canvastutorial= new Canvastutorial();
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
canvasthread = new CanvasThread(getHolder(), this);
setFocusable(true);
}
public MySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
canvasthread = new CanvasThread(getHolder(), this);
setFocusable(true);
}
@Override
public void onDraw(Canvas canvas) {
if(canvas!=null)
{
switch (w)
{
case MENU:
//menu stuff
break;
case GAME:
// WHEN THE GAME IS COMPLETED I CALL THE
//showDialogGameCompleted METHOD WHICH IS IMPLEMENTED IN MY ACTIVITY CLASS
if(gameCompleted)
{
gameCompleted=false;
canvastutorial.showDialogGameCompleted();
}
break;
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
canvasthread.setRunning(true);
canvasthread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
canvasthread.setRunning(false);
while (retry) {
try {
canvasthread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
我的线程类:
public class CanvasThread extends Thread {
private SurfaceHolder _surfaceHolder;
private MySurfaceView _mySurfaceView;
private boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder, MySurfaceView mySurfaceView) {
_surfaceHolder = surfaceHolder;
_mySurfaceView = mySurfaceView;
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas c;
while (_run)
{
c = null;
try
{
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder)
{
_mySurfaceView.onDraw(c);
}
}
finally
{
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null)
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
【问题讨论】:
-
您需要在 UI 线程上执行 所有 UI 操作。使用 runOnUiThread() 执行整个 showDialogGameCompleted() 方法,而不仅仅是 dialog.show()。
-
我试过了,但是我在 android.content.ContextWrapper.getApplicationInfo 得到了 NullPointerException。我将上下文传递给对话框变量的方式有什么问题吗?
标签: android canvas dialog surfaceview looper