Android 在异步线程中启动对话框时出现异常
我有一个创建异步连接的活动,如下所示:Android 在异步线程中启动对话框时出现异常,android,dialog,Android,Dialog,我有一个创建异步连接的活动,如下所示: new Thread(new Runnable() { public void run() { try{ //Make Connection }catch(Exception e){ runOnUiThread(new Runnable() { public void run() {
new Thread(new Runnable() {
public void run() {
try{
//Make Connection
}catch(Exception e){
runOnUiThread(new Runnable() { public void run() {
Dialogs.showErrorDialog(MyActivity.this); //I display an error dialog using this context
} });
}
}
}).start();
想象一下,连接真的很慢,我离开了启动此线程的活动。如果连接最终运行良好,则一切正常,但如果连接失败,则会在启动对话框时崩溃,因为上下文不再存在。错误是:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4068a558 is not valid; is your activity running?
如何避免这个错误?我想检测一下我的活动是否还活着
1) 显示具有此上下文的对话框(如果我仍在屏幕上)
2) 使用ApplicationContext显示祝酒词(如果我在屏幕外)
编辑:
对话框代码如下所示:
static public void showErrorDialog(Context context){
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.error_title);
builder.setMessage(R.string.error_content);
builder.setPositiveButton(R.string.button_ok,null);
builder.show();
}
无法更改线程中的UI;您使用RunOnUiThread,但UiThread仍在线程中。 您可以使用AsyncTask来完成它
class ConnectionTask extends AsyncTask<Void, Void, Boolean> {
protected Boolean doInBackground(Void... params) {
//Make Connection
boolean flag = connecting(); //flag is connect state: success or fail
return flag;
}
protected void onPostExecute(Boolean result) {
if (!result) {
Dialogs.showErrorDialog(MyActivity.this);
}
}
}
如何避免这个错误
我建议你使用这个:
runOnUiThread(new Runnable() {
public void run() {
if (!(((Activity) context).isFinishing())) { // you need to pass Context.
Dialogs.showErrorDialog(context);
}
}
});
让我知道它是否有效
注意:如果它不起作用,我建议您使用
AsyncTask
而不是runOnUiThread()。该活动已完成,但我仍希望在线程为doneyoy时向用户显示一个错误对话框,但用户无法执行此操作。您可以使用另一个活动的上下文来绘制对话框,但不能使用完成活动的上下文仍然不工作,因为对话框启动时上下文已不存在。请粘贴对话框。对话框代码,让我们了解内容尝试以下操作:静态公共对话框(活动上下文){}将上下文更改为活动
runOnUiThread(new Runnable() {
public void run() {
if (!(((Activity) context).isFinishing())) { // you need to pass Context.
Dialogs.showErrorDialog(context);
}
}
});