Reputation: 1812
I have an activity that makes an asynchronous connection, like this:
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();
Imagine that the connection is really slow, and I leaved the activity that launched this thread. If the connection finally goes well, everything is fine, but if the connection fails, it crashes when launching the dialog, as the context does no longer exist. The error is:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4068a558 is not valid; is your activity running?
How to avoid this error? I would like to detect if my activity is still alive to either
1) show a dialog with this context (if I'm still on the screen)
2) show a Toast with ApplicationContext (if I'm outside the screen)
EDITED: The dialog code is this:
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();
}
Upvotes: 1
Views: 706
Reputation: 33515
How to avoid this error?
I suggest you to use this:
runOnUiThread(new Runnable() {
public void run() {
if (!(((Activity) context).isFinishing())) { // you need to pass Context.
Dialogs.showErrorDialog(context);
}
}
});
Let me know if it works.
Note: If it won't works, i recommend to you use AsyncTask
instead of runOnUiThread()
.
Upvotes: 2
Reputation: 2374
can't change UI in thread; you use RunOnUiThread, but the UiThread still in the thread. You can use AsyncTask to do it.
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);
}
}
}
then, use as follows:
ConnectionTask task = new ConnectionTask();
task.execute();
Upvotes: 0