I've been seeing an occasional crash in my Crashlytics logs that I haven't been able to replicate myself. I've searched everywhere and thought I had followed the same guidelines shown everywhere on how to handle creating and dismissing dialogs around an AsyncTask, namely, create and display them from onPreExecute() and dismiss them in onPostExecute(). Am I missing something here?
Here's the complete code for the class:
public class MyActivity extends BaseActivity implements AsyncResponse {
private AlertDialog mAlert;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
populateData();
}
public void processFinish(boolean result){
if(result) {
//setup and start new intent
finish();
}
else{
AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);
//setup alert
mAlert = builder.create();
mAlert.show();
}
}
private void populateData() {
boolean hasConnection = Utility.isNetworkAvailable(this);
if(!hasConnection){
showConnectDialog();
}
MyTask myTask = new MyTask(this);
myTask.delegate = this;
myTask.execute();
}
@Override
protected void onPause(){
super.onPause();
if ( mAlert!=null && mAlert.isShowing() ){
mAlert.cancel();
}
}
private static ProgressDialog mProgressDialog;
private static void showProgressDialog(Context context) {
if (mProgressDialog == null) {
//setup dialog
}
if (! ((Activity) context).isFinishing()) {
mProgressDialog.show();
}
}
private static void dismissProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
@Override
protected void onDestroy() {
dismissProgressDialog();
super.onDestroy();
}
private static class MyTask extends AsyncTask<Void, Void, Boolean> {
final WeakReference<BaseActivity> activityRef;
private AsyncResponse delegate=null;
private PowerManager.WakeLock mWakeLock;
private MyTask(BaseActivity activity) {
activityRef = new WeakReference<>(activity);
}
@Override
protected void onPreExecute() {
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
Context context = activityRef.get();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
mWakeLock.acquire(90000); //1.5 minute timeout
int currentOrientation = context.getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
((Activity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
((Activity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
showProgressDialog(context);
}
@Override
protected void onPostExecute(Boolean result) {
mWakeLock.release();
dismissProgressDialog();
BaseActivity activity = activityRef.get();
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
delegate.processFinish(result);
}
@Override
protected Boolean doInBackground(Void... params) {
DataRetriever retriever = new DataRetriever(activityRef.get());
return retriever.getData();
}
}
}
The exception log shows: Caused by android.view.WindowManager$BadTokenException Unable to add window -- token android.os.BinderProxy@a60eb7a0 is not valid; is your activity running?
android.view.ViewRootImpl.setView (ViewRootImpl.java:559)
android.view.WindowManagerGlobal.addView (WindowManagerGlobal.java:269)
android.view.WindowManagerImpl.addView (WindowManagerImpl.java:69)
android.app.Dialog.show (Dialog.java:281)
com.xxx.MyActivity.showProgressDialog (MyActivity.java:1100)
com.xxx.MyActivity$MyTask.onPreExecute (MyActivity.java:95)
android.os.AsyncTask.executeOnExecutor (AsyncTask.java:586)
android.os.AsyncTask.execute (AsyncTask.java:534)
com.xxx.MyActivity.populateLanguages (LanguagePopulateActivity.java:32)
com.xxx.MyActivity.onCreate (LanguagePopulateActivity.java:9)
Thanks!