Возобновление процесса загрузки после уничтожения пользовательского интерфейса - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть приложение, которое позволяет пользователю выполнять несколько загрузок.

  1. Например, пользователь щелкает значок, появляется фрагмент, начинающий загрузку, и показывает прогресс, обновляя индикатор выполнения.каждую секунду.
  2. Пользователь может нажать кнопку «Назад», фрагмент уничтожается и может нажать другую кнопку, параллельно загружая другой элемент.
  3. Если пользователь возвращается, чтобы нажать первыйзначок, и загрузка все еще продолжается, требуется, чтобы индикатор выполнения отображался автоматически, чтобы пользователь знал, что загрузка еще не завершена.

Моя проблема # 3, где, если пользовательнажимает назад и Asynctask теряет интерфейс, обновления прогресса останавливаются при возобновлении.Как получить обновления для правильного загружаемого элемента, поскольку эта функция предусматривает несколько параллельных загрузок?

В настоящее время я упаковываю AsyncTask во фрагмент, чтобы сохранить экземпляр.Может ли кто-нибудь посоветовать, как правильно сделать это (максимально уменьшить утечки памяти)?

class DownloadTaskFragment : Fragment() {

    private var mCallbacks: TaskCallbacks? = null
    private var mTask: DummyTask? = null


    interface TaskCallbacks {
        fun onPreExecute()
        fun onProgressUpdate(progress: Int)
        fun onCancelled()
        fun onPostExecute()
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        retainInstance = true

        mTask = DummyTask(this)
        mTask!!.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
    }

    fun setCallBackInterface(taskCallback: TaskCallbacks) {
        mCallbacks = taskCallback
    }

    override fun onDetach() {
        super.onDetach()
        mCallbacks = null
    }


    class DummyTask// only retain a weak reference to the activity
    internal constructor(context: DownloadTaskFragment) : AsyncTask<String, Int, Int>() {

        private val reference: WeakReference<DownloadTaskFragment> = WeakReference(context)
        private var mCallbacks: TaskCallbacks? = reference.get()!!.mCallbacks


        override fun onPreExecute() {
            if (mCallbacks != null) {
                mCallbacks!!.onPreExecute()
            }
        }

        override fun doInBackground(vararg params: String?): Int {
            var i = 0
            while (!isCancelled && i < 80) {
                SystemClock.sleep(100)
                publishProgress(i)
                i++
            }

            return 1
        }

        override fun onProgressUpdate(vararg values: Int?) {
            super.onProgressUpdate(*values)
            if (mCallbacks != null) {
                mCallbacks!!.onProgressUpdate(values[0]!!)
            }
        }

        override fun onPostExecute(result: Int?) {
            if (mCallbacks != null) {
                mCallbacks!!.onPostExecute()
            }
        }

        override fun onCancelled() {
            if (mCallbacks != null) {
                mCallbacks!!.onCancelled()
            }
        }
    }

}

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Я бы настоятельно рекомендовал использовать WorkManager для этого.Инструкции по его использованию можно найти здесь .

Если вам нужно установить связь между WorkManager и Fragment, вы можете использовать для этого LiveData<T>. Здесь - статья, описывающая случай.

0 голосов
/ 22 февраля 2019

Чтобы убедиться, что задача продолжается в фоновом режиме (особенно с повышенными ограничениями в API 26+), вам необходимо создать службу переднего плана .Примечание: вы ДОЛЖНЫ показать сопроводительное уведомление (это может быть просто индикатор выполнения)

В качестве службы переднего плана ваша задача будет выполняться отдельно от основного пользовательского интерфейса и, следовательно, не будет подвергаться никаким изменениям в пользовательском интерфейсе.Вы также можете обновить пользовательский интерфейс службы (см. здесь для получения дополнительной информации)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...