I have an app with many activities, and lots of them hit various json web APIs to load & show data. A common pattern is similar to:
public class MyActivity extends Activity {
public void OnCreate(Bundle savedInstanceState) {
...
ProgressDialog pd = ProgressDialog.show( ... );
// This is a custom API which wraps AsynkTask and calls my callback in onPostExecute
DoWebThing(url, new Callback() {
public void onSuccess(String json) {
pd.dismiss();
// Do other UI stuff with the json data
}
});
}
}
This works great, and is similar to a lot of code snippets you'll find on SO and tutorials. The problem is that the user can leave the page while the background process is running. In this case, I get a logcat error about leaking the view (the ProgressDialog), and then I'll crash when I dismiss it or do my other UI stuff.
I've tried adding an early check in onSuccess:
if (!pd.isShowing()) {
return;
}
This fixes the crash on some devices, but not others, and we still get the logcat error about a leaked view.
I've tried replacing the pd.isShowing()
check with MyActivity.this.isFinishing()
, which doesn't help with anything (on the device I'm currently testing with). Still get the logcat error and crash.
I've tried MyActivity.this.isDestroyed()
, which fixes the crash, but only works on SDK 17+ and still get the logcat error.
The only option to truly fix this is to make my progress dialog a member variable and override OnDestroy()
:
ProgressDialog mPd;
@Override
protected void onDestroy() {
super.onDestroy();
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
Now in my callback I can check if mProgressDialog == null
.
This works great. No crash and no logcat error about leaking a view. But it feels like a lot of boilerplate - I have to make the progress dialog a member variable and override OnDestroy()
in all of my (many) activities that do background stuff.
I'm not seeing a better option, but wanted a second opinion before I start updating lots of activities.