admin / 22.08.2018

Работа с потоками через AsyncTask | android | programming

.

Концепция и код здесь

Я создал простой пример использования AsyncTask для Android. Он начинается с и, наконец, .

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

Однако, если вам нужно обновить какой-либо виджет из вы можете из который будет вызывать для обновления виджета пользовательского интерфейса.

Назовите это так:

Справочник разработчика здесь

теория

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

Пользователь должен всегда иметь возможность взаимодействовать с приложением, и важно не блокировать основной поток (UI) такими задачами, как загрузка содержимого из Интернета. Это когда мы будем использовать .

В потоке пользовательского интерфейса есть очередь сообщений и обработчик, который позволяет отправлять и обрабатывать выполняемые объекты и сообщения, часто из других потоков. AsyncTask обертывает это поведение прямым интерфейсом.

Реализация

— это общий класс. (Это означает, что в его конструкторе требуются параметризованные типы. Каждый общий параметр определяется как аргумент переменной Java с тремя точками: и поэтому технически передается как массив).

Три типа, используемые : , и :

  1. Парамс — тип параметра, отправленный в задачу при выполнении
  2. Прогресс — тип, опубликованный для обновления хода во время фонового вычисления
  3. Результат — тип результата фонового вычисления

Эти три параметра соответствуют трем основным функциям, которые вы можете переопределить в :

  • также:

Выполнение AsyncTask

вызов с параметрами, которые необходимо отправить в фоновое задание.

Что происходит

  1. На основном / UI-потоке . (Чтобы инициализировать что-то в этом потоке.)
  2. В фоновом потоке с параметрами, переданными функции Execute.
    • Для использования AsyncTask необходимо переопределить хотя бы .
    • Где должна выполняться долгосрочная задача
    • вызовите с параметрами чтобы обновить некоторый пользовательский интерфейс с выполнением долговременной задачи. Это вызывает .
  3. В фоновом потоке результат возвращается из задачи в , что вызывает
  4. В главном / пользовательском потоке с возвращенным результатом.

пример

Повторяя пример задачи блокирования, заключающейся в загрузке чего-либо из Интернета, следующий пример загружает изображение и отображает его в ImageView. Метод загружает изображение и сохраняет его в объекте типа BitMap.

Как работать с AsyncTask в Android?

Метод принимает растровое изображение и помещает его в ImageView.

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

Когда вы используете AsyncTask, пожалуйста, поймите методы обратного вызова.

Например:

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

Например:

Это поможет вам лучше узнать все. Следовательно, в вашем случае вам необходимо установить текстовое представление в методе onPostExecute ().

Если вы уже знакомы с понятием потока, то разобраться с AsyncTask в Андроид-приложениях не составит труда. AsyncTask или асинхронная задача — это кусок кода, который может представлять собой фоновую активность в отдельном потоке. AsyncTask позволяют избежать блокировки интерфейса в то время, когда система занята выполнением какой-то «тяжелой» задачи.

Рассмотрим простой пример, в котором задача такого типа будет обновлять в TextView значение — это будет цикл, на каждой итерации которого мы будем выводить на экран номер этой самой итерации (с некоторой задержкой). Получится своего рода таймер. Пока будет работать данный процесс мы попробуем вводить в поле EditText какую-то строку и обновлять по клику на кнопке введенным значением другой элемент TextView. Этим самым мы проверим блокируется ли интерфейс вычислениями или нет.

Итак, нам понадобиться создать:

— activity_main.xml
— MainActivity.java

Layout нашего приложения res/layout/activity_main.xml:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center|top" android:orientation="vertical" >   <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="25dp" android:text="@string/app_name" />   <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" />   <EditText android:id="@+id/edTxt" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" > </EditText>   <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Изменить текст" android:onClick="btnClick"/>   </LinearLayout>

Для кнопки добавлено свойство android:onClick, в котором задан метод-обработчик клика — btnClick(). Создадим класс активити с основной логикой, но саму асинхронную задачу с вычислениями поместим во внутренний класс — TheTask.

MainActivity.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 package ru.androiddocs.thetask;   import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.TextView;   import java.util.concurrent.TimeUnit;     public class MainActivity extends ActionBarActivity {   private static final String LOG_TAG = "my_tag";   TextView mTv, mTvChange; EditText mEdTxt; String mResult;   @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mEdTxt = (EditText) findViewById(R.id.edTxt); mTvChange = (TextView) findViewById(R.id.tv2);   new TheTask().execute("Текущий результат: "); }   public void btnClick(View v) { mTvChange.setText(mEdTxt.getText().toString()); }   class TheTask extends AsyncTask<String, Integer, String> {     @Override protected void onPreExecute() { super.onPreExecute(); mTv = (TextView) findViewById(R.id.tv); }   @Override protected String doInBackground(String… strData) { try { for (int i = 0; i < 60; i++) { mResult = strData[0] + i; publishProgress(i); TimeUnit.SECONDS.sleep(3); } } catch (InterruptedException e) { e.printStackTrace(); }   return mResult; }   @Override protected void onProgressUpdate(Integer…

Пример Android для AsyncTask

currInt) { super.onProgressUpdate(currInt); mTv.setText("" + currInt[0]); }   @Override protected void onPostExecute(String result) { super.onPostExecute(result);   Log.d(LOG_TAG, result); } } }

В методе onCreate() мы получаем доступ до нужных элементов View и запускаем асинхронную задачу, передавая ей в качестве параметра строку (мы ее будем использовать при обновлении процессом TextView:

1 new TheTask().execute("Текущий результат: ");

Сам класс TheTask наследуется от класса AsyncTask. Используется три параметра:

1 <String, Integer, String>.

Первый — это передаваемый в класс параметр (если передаете число, то нужно изменить, например, на Integer). Второй параметр типа Integer используется для промежуточных результатов при вызове метода onProgressUpdate() и третий типа String используется для финального результата (возвращаемого значения).

Суть методов:

onPreExecute() — срабатывает перед запуском задачи
doInBackground() — непосредственно сама асинхронная задача (фоновая работа)
onProgressUpdate() — метод, вызываемый в процесс работы задачи. Используется для обновления прогресса выполнения
onPostExecute() — метод, срабатывающий в самом конце задачи, и получает итоговый результат

Вызов метода onProgressUpdate() делается с помощью publishProgress(), где с параметром мы передаем номер итерации (как вы помните, для промежуточных результатов мы можем использовать только целые числа — Integer). Полученное число выводим в TextView.

В заключительном методе onPostExecute() выводим в логи итоговый результат. По сути, это объединение строки «Текущий результат: » и номера последней итерации.

Запускаем и тестируем. Пока идут вычисления мы легко можем вводить что-то в текстовое поле и обновлять TextView.

Если, например, вы не используете «промежуточный» метод onProgressUpdate(), то определение класса TheTask может быть таким:

1 class TheTask extends AsyncTask<String, Void, String>

Рубрика: Разное

Справочник по android API

Потоки

В андроиде добавлены дополнительные возможности для работы с потоками.

Класс Handler

Когда объект Handler создается, он назначается текущему потоку и его очереди сообщений. После этого он может доставлять сообщения и код (Runnable) в очередь сообщений для обработки и выполнения их в будущем.

Полный список

Таким образом, объект используется для одновременной обработки сообщений и выполнения некоторого кода или для выполнения кода в другом потоке. Ниже приведены некоторые методы класса:

  • dispatchMessage(Message msg) — обработчик системных сообщений
  • dump(Printer pw, String prefix) — дамп
  • handleMessage(Message msg) — обработчик входящих сообщений, должен переопределятся потомками
  • hasMessages(int what, Object object) — проверяет есть ли не обработанное сообщение с кодом 'what' и объектом сообщения 'object'
  • hasMessages(int what) — проверяет есть ли не обработанное сообщение с кодом 'what'
  • Message obtainMessage() — новое сообщение из глобального пула сообщений, есть вариации метода
  • boolean post(Runnable r) — послать r в очередь сообщений (т.е. выполнить код в потоке, в котором объект Handle был создан)
  • void removeCallbacks(Runnable r) — удалить все посланные r из очереди сообщений
  • void removeMessages(int what) — удалить сообщение с кодом 'what' из очереди
  • boolean sendMessage(Message msg) — поместить сообщение в конец очереди сообщений

метод runOnUiThread

Метод runOnUiThread класса Activity позволяет выполнить указанный код в UI потоке. Если текущий поток — UI поток, то он выполняется сразу, иначе помещается в очередь событий UI потока.

Обычно используется, когда нужно изменить элементы управления после выполнения какой-то задачи в другом потоке.

метод View.post

Если пытаться получить высоту TextView после изменения содержимого, результат скорей всего будет неверным.

В этом случае высота запрашивается через метод post класса View. Указанная задача будет добавлена в очередь сообщений и выполнена в потоке UI.

FILED UNDER : IT

Submit a Comment

Must be required * marked fields.

:*
:*