Избегать шаблонных с ProgressDialog и AsyncTask? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть приложение со множеством действий, и многие из них используют различные веб-API json для загрузки и отображения данных.Общий шаблон похож на:

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
            }
        });
    }
}

Это прекрасно работает и похоже на множество фрагментов кода, которые вы найдете в SO и руководствах.Проблема в том, что пользователь может покинуть страницу во время работы фонового процесса.В этом случае я получаю сообщение logcat об утечке представления (ProgressDialog), а затем выхожу из строя, когда отклоняю его или выполняю другие операции с пользовательским интерфейсом.

Я попытался добавить раннюю проверкуonSuccess:

if (!pd.isShowing()) {
    return;
}

Это исправляет сбой на некоторых устройствах, но не на других, и мы по-прежнему получаем ошибку logcat о просочившемся представлении.

Я пытался заменить pd.isShowing()сверьтесь с MyActivity.this.isFinishing(), который ничего не помогает (на устройстве, с которым я сейчас тестирую).По-прежнему получаю ошибку logcat и сбой.

Я пробовал MyActivity.this.isDestroyed(), который исправляет сбой, но работает только на SDK 17+ и по-прежнему получает ошибку logcat.

Единственный вариантчтобы по-настоящему исправить это, нужно сделать мой диалог прогресса переменной-членом и переопределить OnDestroy():

ProgressDialog mPd;
@Override
protected void onDestroy() {
    super.onDestroy();
    if (mProgressDialog != null) {
        mProgressDialog.dismiss();
        mProgressDialog = null;
    }
}

Теперь в моем обратном вызове я могу проверить, mProgressDialog == null.

Это прекрасно работает.Нет сбоев и ошибок logcat по поводу утечки представления.Но это похоже на много шаблонов - я должен сделать диалог прогресса переменной-членом и переопределить OnDestroy() во всех моих (многих) действиях, которые выполняют фоновые операции.

Я не вижу лучшеговариант, но хотелось бы получить второе мнение, прежде чем я начну обновлять множество действий.

1 Ответ

0 голосов
/ 21 сентября 2018

Создайте одно действие, скажем, NetworkBaseActivity.Создайте ProgressDialog и обработайте onDestroy в этом упражнении.Также создайте метод с именем showMyDialog() и hideMyDialog(), чтобы показать и скрыть диалог (из подклассов).Теперь все ваши действия, которые делают фоновые вещи, должны только продлить это действие.Чтобы показать диалог вызова showMyDialog() и скрыть его вызов hideMyDialog()

Примерно так:

public class NetworkBaseActivity extends AppCompatActivity{
    ProgressDialog myDialog;
    onCreate(Bundle bundle){
        // initialize myDialog
    }

    public void showDialog(){
       // show myDialog if not shown
    }
    public void hideDialog(){
      // hide myDialog if already shown
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mProgressDialog != null) {
        mProgressDialog.dismiss();
        mProgressDialog = null;
    }
}

public class YourActivity extends NetworkBaseActivity{

}

Я набрал код прямо в stackoverflow, так что извините за мои опечатки, но вы получитеидея.

...