Сбой приложения при изменении ориентации при отображении индикатора выполнения в AsyncTask

У меня есть приложение, которое использует AsyncTask для получения файла json с сервера и поэтому показывает индикатор выполнения. Но при отображении индикатора выполнения и изменении ориентации приложение вылетает с ошибкой VIEW NOT ATTACHED или HAS LEAKED WINDOW.

Как избавиться от этих ошибок? В противном случае приложение отлично работает на AsyncTask.


person aman.nepid    schedule 05.12.2012    source источник
comment
покажите код, чтобы мы могли помочь!   -  person hardartcore    schedule 05.12.2012
comment
@Android-Developer: у меня есть простой класс AsyncTask с doInBackground только onPreExecute и onPostExecute.   -  person aman.nepid    schedule 05.12.2012
comment
поэтому вам просто нужно закрыть диалоговое окно прогресса в onPause, и если асинхронная задача все еще выполняется, покажите ее снова в вашем onResume();   -  person hardartcore    schedule 05.12.2012


Ответы (5)


Попробуйте это для своей деятельности. Хотя там не очень чисто. Это может помочь

<activity android:configChanges="orientation|screenSize" android:name=".activity.MyActivity" ></activity>
person Artem Zelinskiy    schedule 05.12.2012

А как насчет «блокировки» ориентации экрана во время работы AsyncTask?!

Например:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

прямо перед тем, как вы получите файл JSON с сервера и

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

после выполнения вашего AsynTask.

person reVerse    schedule 05.12.2012
comment
Это то, о чем я тоже думал. - person Ayush Goyal; 05.02.2013
comment
+1 за принудительную настройку пользователя только тогда, когда вам это действительно нужно. - person ironicaldiction; 17.07.2013
comment
Самый лучший и простой способ!! - person ambit; 24.07.2013
comment
меня попросили создать метод setRequestedOrientation. Как я могу использовать setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); когда моя асинтаск в другом классе. Спасибо! - person lolliloop; 29.08.2013

Мое лучшее предположение из ограниченной информации, доступной на данный момент:

Когда вы поворачиваете экран, он проходит через нормальный процесс жизненного цикла активности onPause(), onStop() и onDestroy() соответственно, поэтому вам нужно отклонить progressDialog в одном из этих методов.

Как я это сделал:

@Override
protected void onPause()
{
    super.onPause();
    if (mProgressDialog != null)
        mProgressDialog.dismiss();
}
person Stupidus    schedule 05.12.2012

Попробуйте этот небольшой хак, который я собрал... запустите его и наблюдайте за информацией logcat, когда вы пробуете различные комбинации изменений экрана и нажатия аппаратной клавиши возврата. Затем попробуйте настройку, упомянутую в комментариях ниже, и поработайте еще немного. Это позволяет избежать использования android:configChanges="orientation|screenSize", что нежелательно.

Это должно быть собрано как есть с минимальным манифестом и файлом layout.xml. Оставляйте комментарии, если я как-то накосячил.

// ********************************************************************
// *** AsynchHack - allows for multiple screen orientation changes, ***
// ***    multiple asynch tasks are started / stopped,progress      ***
// ***    dialogs handled gracefully (no memory leaks / etc).       ***
// ***                                                              ***
// ***    Remove the wrapping comments in the onCreate() function   ***
// ***    to restrict processing to a single asynch instantiation   ***
// ***    screen rotation will dismiss the progress meter, but not  ***
// ***    the task                                                  ***
// ***                                                              ***
// ***    View the logcat to understand the timing of events and    ***
// ***    their interactions                                        ***
// ***                                                              ***
// ********************************************************************

package com.example.AsynchHack;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.util.List;

// *** Main activity

public class AsynchHack extends Activity {

    final static String debugClass = "AsynchHack";
    ProgressDialog mProgressDialog;

    // *** standard onCreate()

    public void onCreate(Bundle aSavedInstanceState) {

        super.onCreate(aSavedInstanceState);
        Log.d(debugClass, "onCreate(" + this + ")");
        setContentView(R.layout.layout);

        // As-is, this allows for multiple starts of asynch tasks
        //if (aSavedInstanceState == null) {
        mProgressDialog = new ProgressDialog(this);
        (new AsynchStartup()).execute();
        //}

    }

    // *** demo Asynch task

    private class AsynchStartup extends AsyncTask<Void, Void, Void> {

        protected void onPreExecute() {
            Log.d(debugClass,
                  "--- AsynchStartup() onPreExecute  (" + this + ")");
            mProgressDialog.setMessage("Loading please wait..");
            mProgressDialog.show();
        }

        protected Void doInBackground(Void... aInput) {
            Log.d(debugClass,
                  "--- AsynchStartup() doInBackground(" +
                  this + ") *starts*");

            // simulate lengthy processing
            try {
                Thread.sleep(5000);
            }
            catch (InterruptedException aException) { }

            Log.d(debugClass,
                  "--- AsynchStartup() doInBackground(" +
                  this + ") *finishes*");
            return null;
        }

        protected void onProgressUpdate(Void aProgress){
        }

        protected void onPostExecute(Void aOutput) {
            Log.d(debugClass,
                  "--- AsynchStartup() onPostExecute (" + this + ")");

            if (mProgressDialog != null) {
                Log.d(debugClass,
                      "--- AsynchStartup() onPostExecute " +
                      "(Dismissing progress meter)");
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
            else {
                Log.d(debugClass,
                      "--- AsynchStartup() onPostExecute " +
                      "(Not required to dismiss progress meter)");
            }
        }

    }

    // *** standard onDestroy()

    public void onDestroy() {

        super.onDestroy();
        Log.d(debugClass, "onDestroy(" + this + ")");

        if (mProgressDialog != null) {
            Log.d(debugClass,
                 "onDestroy(Dismissing progress meter)");
            mProgressDialog.dismiss();
            mProgressDialog = null;
        }
        else {
            Log.d(debugClass,
                  "onDestroy(Not required to dismiss progress meter)");
        }

    }

}
person capella    schedule 09.12.2012

Попробуйте использовать это

  dialog.setCancelable(false);
person Ali Imran    schedule 05.12.2012
comment
некоторое объяснение поможет этому ответу - person dove; 05.12.2012