Попросить внешний класс перезвонить AsyncTask для обновления прогресса - PullRequest
1 голос
/ 17 апреля 2011

Я выполняю упражнение, которое должно загрузить довольно большое изображение из Интернета, а затем отобразить его. Это работает: загрузка выполняется через AsyncTask, и отображается диалог прогресса. И когда загрузка заканчивается, вызывается действие, показывающее изображение.

У меня проблема в том, что настоящая работа выполняется во внешнем классе. Это так же, как другие действия вызывают ту же процедуру для получения изображения. Поэтому я не могу сразу вызвать postUpdate (), чтобы установить обновление, так как этот вызов будет выполнен в другом классе. Теперь мне интересно, как я могу получить обновления прогресса в свой AsyncTask, чтобы мой диалог прогресса мог показать фактический достигнутый прогресс

Подкласс AsyncTask в настоящее время выглядит так:

private class StartShowImage extends AsyncTask<String, Integer, String> {

    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {

        // Toon een dialog met draaiend wiel terwijl we de foto
        // aan het ophalen zijn.
        dialog = new ProgressDialog(ShowDeaddrop.this);
        dialog.setTitle(R.string.progress_dialog_title);
        dialog.setMessage(getResources().getString(
                R.string.progress_dialog_fetching_image));
        dialog.show();
    }

    /**
     * De hoofdroutine; haalt de foto op.
     */
    @Override
    protected String doInBackground(final String... params) {
        final String imageName = params[0];
        String result = null;
        try {
            result = DeaddropUtil.getImage(context, imageName, ""
                    + deaddropID, true);
        } catch (final IOException e) {
            Log.v(TAG, "Failed to download image " + imageName);
            Log.v(TAG, "" + e);
        }
        return result;
    }

    /**
     * Als we de foto hebben, start ShowImage.
     */
    @Override
    protected void onPostExecute(final String imageName) {
        dialog.dismiss();
        if (isActive)
            if (imageName == null)
                Toast.makeText(context, R.string.toast_show_image_failed,
                        Toast.LENGTH_SHORT).show();
            else {
                final Intent i = new Intent(ShowDeaddrop.this,
                        ShowImage.class);
                i.putExtra("imageName", imageName);
                startActivityForResult(i, SHOW_IMAGE);
            }
    }
     }

isActive - это логическое значение, которое отслеживает, является ли это действие активным - оно установлено в onCreate и onResume и сброшено в onPause.

Я искал намерение вещания - я видел пример того, как отправить такое намерение в основное действие, но проблема в том, что слушатель должен быть зарегистрирован / не зарегистрирован в onResume / onPause - и AsyncTask является отдельным потоком. Таким образом, кажется, что этот метод не может быть безопасно использован таким образом.

Отредактируйте повторный вопрос, надеясь получить ответы на мой вопрос.

AsyncTask устанавливает диалог прогресса.

Поток onExecute () может напрямую обновлять диалог прогресса. Там нет проблем.

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

У AsyncTask должен быть какой-то слушатель, или обработчик, или что-то, к чему может обращаться внешний класс, чтобы обновлять информацию о прогрессе.

Вопрос: как выполнить эту последнюю часть процесса? Что такое подходящий слушатель? Как реализовать такого слушателя? В каком потоке заканчивается слушатель - поток пользовательского интерфейса, например .onPreExecute () и .onPostExecute (), или рабочий поток из .doInBackground ()?

Ответы [ 3 ]

2 голосов
/ 25 апреля 2011

Решено с помощью BroadcastIntent.

Основное действие - создание BroadcastReceiver, IntentFilter и диалогового окна хода выполнения;AsyncTask регистрирует / отменяет регистрацию этого получателя и показывает / закрывает диалоговое окно в onPreExecute / onPostExecute соответственно.

С дополнительными битами в onResume и onPause, чтобы не иметь активных получателей, когда само действие неактивно.

ЭтоМне потребовалось некоторое время, чтобы понять эту намеренную трансляцию, но после этого это была очень быстрая и простая реализация.

0 голосов
/ 18 апреля 2011

У вашего класса StartShowImage нет участников.Этот объект вы также использовали для создания тоста.если вы создаете элемент Activity и декларацию конструкции для него, вы можете инициализировать его с помощью конструктора следующим образом, прежде чем вызывать его публичный метод, который вы хотите сделать:

private Activity context;
public StartShowImage(Activity context){
    this.context=context;
}

StartShowImage object=new StartShowImage(this)
object.postUpdate();

Это должно работать, и ваш вызывающий класс должен расширятьсяActivity

0 голосов
/ 18 апреля 2011

Если я правильно понимаю, вы хотите обновить индикатор выполнения из асинхронной задачи.Я бы, вероятно, посмотрел на onProgressUpdate асинхронной задачи.http://developer.android.com/reference/android/os/AsyncTask.html

...