这是我的 AlertDialog 无响应状态的屏幕截图:
在背景中,绿色瓷砖,黑白目标内的红球,所有三个位图都在渲染线程上连续渲染,该渲染线程锁定/解锁我手机上的背景画布。无论我在 EditText 中输入了什么文本,当我按下 OK 按钮时,总是会执行这个无响应的操作。
这是代码:
PlayActivity 类:
package nttu.edu.activities;
import nttu.edu.graphics.RenderView;
import nttu.edu.handler.Accelero;
import nttu.edu.handler.TouchHandler;
import nttu.edu.score.Score;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
public class PlayActivity extends Activity implements OnClickListener
{
public RenderView renderView = null;
public Accelero accelerometer = null;
public AssetManager assetManager = null;
public TouchHandler touchHandler = null;
public Score leaderboard = null;
final int REQUEST_CODE = 0x1;
private EditText input = null;
private AlertDialog.Builder dialog = null;
public void onCreate(Bundle b)
{
super.onCreate(b);
accelerometer = new Accelero();
touchHandler = new TouchHandler();
leaderboard = new Score(this);
renderView = new RenderView(this, accelerometer, touchHandler);
renderView.setOnTouchListener(touchHandler);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
input = new EditText(this);
dialog = new AlertDialog.Builder(this);
dialog.setTitle("Enter High Score!");
dialog.setMessage("Enter your name: ");
dialog.setView(input);
dialog.setPositiveButton("OK", PlayActivity.this);
setContentView(renderView);
}
public void onResume()
{
super.onResume();
if(renderView != null)
renderView.resume();
if(accelerometer != null)
accelerometer.resume(this);
}
public void onPause()
{
super.onPause();
if(renderView != null)
renderView.pause();
if(accelerometer != null)
accelerometer.pause();
}
public void addPlayer()
{
// FIXME: The dialog won't exit.
Looper.prepare();
dialog.show();
Looper.loop();
}
public void onClick(DialogInterface dialog, int button)
{
String name = input.getText().toString();
if(name == null)
name = "Player";
this.leaderboard.open();
this.leaderboard.createEntry(name, this.renderView.getScore());
this.leaderboard.close();
if (Looper.myLooper() != null)
Looper.myLooper().quit();
else if (Looper.getMainLooper() != null)
Looper.getMainLooper().quit();
Log.d("PlayActivity.onClick()", "I'm escaping from Looper.loop()");
//renderView.running = false;
//PlayActivity.this.finish();
}
}
由于某些未知原因,AlertDialog 仅在调用 AlertDialog.show() 之前存在准备好的 Looper 时才会执行。
问题是在调用 AlertDialog.show() 之后,在调用 Looper.quit() 之后,AlertDialog 不知何故没有退出,这使得手机无响应。
当我在 onClick() 方法中调用 PlayActivity.this.finish() 时,我可以退出对话框,停止后台渲染,然后返回主菜单(这是我想要的),但是 Eclipse DDMS 报告了这个:
06-26 16:40:29.049: E/WindowManager(1642): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
06-26 16:40:29.049: E/WindowManager(1642): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
06-26 16:40:29.049: E/WindowManager(1642): at android.view.Window$LocalWindowManager.addView(Window.java:433)
06-26 16:40:29.049: E/WindowManager(1642): at android.app.Dialog.show(Dialog.java:265)
06-26 16:40:29.049: E/WindowManager(1642): at android.app.AlertDialog$Builder.show(AlertDialog.java:802)
06-26 16:40:29.049: E/WindowManager(1642): at nttu.edu.activities.PlayActivity.addPlayer(PlayActivity.java:77)
06-26 16:40:29.049: E/WindowManager(1642): at nttu.edu.graphics.RenderView.tick(RenderView.java:119)
06-26 16:40:29.049: E/WindowManager(1642): at nttu.edu.graphics.RenderView.run(RenderView.java:69)
06-26 16:40:29.049: E/WindowManager(1642): at java.lang.Thread.run(Thread.java:1027)
06-26 16:40:29.079: W/MessageQueue(1642): Handler{405399b8} sending message to a Handler on a dead thread
06-26 16:40:29.079: W/MessageQueue(1642): java.lang.RuntimeException: Handler{405399b8} sending message to a Handler on a dead thread
06-26 16:40:29.079: W/MessageQueue(1642): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
简而言之,当我想通过调用 finish() 退出 PlayActivity 时,AlertDialog 会泄漏。我不知道还能做些什么来解决这个问题。
请帮我。谢谢!如果您需要更多源代码,请告诉我。
编辑:
就在泄漏错误出现之前,这是 DDMS 记录的内容:
06-26 16:40:22.182: D/Level.render()(1642): Drawing Tee.
06-26 16:40:22.182: D/Level.render()(1642): Drawing Hole.
06-26 16:40:22.182: D/Level.render()(1642): Drawing Ball.
06-26 16:40:22.192: D/Level.render()(1642): Drawing background.
06-26 16:40:22.202: D/Level.render()(1642): Drawing Tee.
06-26 16:40:22.202: D/Level.render()(1642): Drawing Hole.
06-26 16:40:22.202: D/Level.render()(1642): Drawing Ball.
06-26 16:40:22.212: D/Level.render()(1642): Drawing background.
06-26 16:40:22.212: D/Level.render()(1642): Drawing Tee.
06-26 16:40:22.222: D/Level.render()(1642): Drawing Hole.
06-26 16:40:22.222: D/Level.render()(1642): Drawing Ball.
06-26 16:40:22.222: D/FrameRate(1642): 59
06-26 16:40:22.232: D/Level.tick()(1642): Obtaining score.
06-26 16:40:22.232: D/Level.render()(1642): Drawing background.
06-26 16:40:22.232: D/Level.render()(1642): Drawing Tee.
06-26 16:40:22.242: D/Level.render()(1642): Drawing Hole.
06-26 16:40:22.242: D/Level.render()(1642): Drawing Ball.
06-26 16:40:22.242: D/Level.render()(1642): Outputting the phrase: Game Over
06-26 16:40:23.713: D/Database(1642): dbopen(): path = /data/data/nttu.edu/databases/Scoreboard, flag = 6, file size = 5120
06-26 16:40:23.713: D/Database(1642): dbopen(): path = /data/data/nttu.edu/databases/Scoreboard, mode: wal, disk free size: 1014 M, handle: 0x38b4a8
06-26 16:40:23.844: D/Database(1642): dbclose(): path = /data/data/nttu.edu/databases/Scoreboard, handle = 0x38b4a8
06-26 16:40:28.608: D/PlayActivity.onClick()(1642): I'm escaping from Looper.loop()
06-26 16:40:28.618: D/Level.render()(1642): Drawing background.
06-26 16:40:28.628: D/Level.render()(1642): Drawing Tee.
06-26 16:40:28.628: D/Level.render()(1642): Drawing Hole.
06-26 16:40:28.628: D/Level.render()(1642): Drawing Ball.
06-26 16:40:28.628: D/Level.render()(1642): Outputting the phrase: Game Over
06-26 16:40:28.648: D/FrameRate(1642): 2
06-26 16:40:28.798: W/MessageQueue(1642): Handler{4053dbd0} sending message to a Handler on a dead thread
06-26 16:40:28.798: W/MessageQueue(1642): java.lang.RuntimeException: Handler{4053dbd0} sending message to a Handler on a dead thread
06-26 16:40:28.798: W/MessageQueue(1642): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
06-26 16:40:28.798: W/MessageQueue(1642): at android.os.Handler.sendMessageAtTime(Handler.java:457)
06-26 16:40:28.798: W/MessageQueue(1642): at android.os.Handler.sendMessageDelayed(Handler.java:430)
06-26 16:40:28.798: W/MessageQueue(1642): at android.os.Handler.sendMessage(Handler.java:367)
06-26 16:40:28.798: W/MessageQueue(1642): at com.android.internal.view.IInputConnectionWrapper.dispatchMessage(IInputConnectionWrapper.java:240)
06-26 16:40:28.798: W/MessageQueue(1642): at com.android.internal.view.IInputConnectionWrapper.finishComposingText(IInputConnectionWrapper.java:151)
06-26 16:40:28.798: W/MessageQueue(1642): at com.android.internal.view.IInputContext$Stub.onTransact(IInputContext.java:137)
06-26 16:40:28.798: W/MessageQueue(1642): at android.os.Binder.execTransact(Binder.java:320)
06-26 16:40:28.798: W/MessageQueue(1642): at dalvik.system.NativeStart.run(Native Method)
06-26 16:40:28.888: W/MessageQueue(1642): Handler{405399b8} sending message to a Handler on a dead thread
06-26 16:40:28.888: W/MessageQueue(1642): java.lang.RuntimeException: Handler{405399b8} sending message to a Handler on a dead thread
06-26 16:40:28.888: W/MessageQueue(1642): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
06-26 16:40:28.888: W/MessageQueue(1642): at android.os.Handler.sendMessageAtTime(Handler.java:457)
06-26 16:40:28.888: W/MessageQueue(1642): at android.os.Handler.sendMessageDelayed(Handler.java:430)