Урок 90. AsyncTask. Status – статусы задачи
В этом уроке:
- читаем статусы задачи
Мы всегда можем определить, в каком состоянии сейчас находится задача. Для этого используются статусы. Их всего три:
PENDING – задача еще не запущена
RUNNING – задача в работе
FINISHED – метод onPostExecute отработал, т.е. задача успешно завершена
В принципе по названиям все понятно, но посмотрим и убедимся сами. К тому же, не очень понятно, в каком статусе будет задача, если мы ее отменим методом cancel.
Рассмотрим на примере.
Создадим проект:
Project name: P0901_AsyncTaskStatus
Build Target: Android 2.3.3
Application name: AsyncTaskStatus
Package name: ru.startandroid.develop.p0901asynctaskstatus
Create Activity: MainActivity
strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">AsyncTaskStatus</string>
<string name="start">Start</string>
<string name="status">Status</string>
</resources>
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onclick"
android:text="@string/start">
</Button>
<Button
android:id="@+id/btnStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onclick"
android:text="@string/status">
</Button>
<TextView
android:id="@+id/tvInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="">
</TextView>
</LinearLayout>
По кнопке Start запускаем задачу, по кнопке Status будем выводить ее статус.
MainActivity.java:
package ru.startandroid.develop.p0901asynctaskstatus;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
MyTask mt;
TextView tvInfo;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tvInfo = (TextView) findViewById(R.id.tvInfo);
}
public void onclick(View v) {
switch (v.getId()) {
case R.id.btnStart:
startTask();
break;
case R.id.btnStatus:
showStatus();
break;
default:
break;
}
}
private void startTask() {
mt = new MyTask();
}
private void showStatus() {
if (mt != null)
Toast.makeText(this, mt.getStatus().toString(), Toast.LENGTH_SHORT).show();
}
class MyTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
tvInfo.setText("Begin");
}
@Override
protected Void doInBackground(Void... params) {
try {
for (int i = 0; i < 5; i++) {
if (isCancelled()) return null;
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
tvInfo.setText("End");
}
@Override
protected void onCancelled() {
super.onCancelled();
tvInfo.setText("Cancel");
}
}
}
По нажатию кнопки Start срабатывает метод startTask. В нем мы просто создаем новую задачу, но пока что не запускаем ее.
По нажатию кнопки Status читаем и выводим на экран статус задачи. Используем метод getStatus.
Сама задача проста, гоняем в цикле паузы.
Все сохраним и запустим.
Жмем Start – задача создалась.
Жмем Status
Статус = PENDING. Все верно, задача еще не запущена.
Перепишем метод startTask:
private void startTask() {
mt = new MyTask();
mt.execute();
}
Теперь будем создавать задачу и запускать ее.
Сохраняем, запускаем. Жмем Start. Задача начала работать.
Жмем Status, пока задача работает
Статус = RUNNING. Задача в работе.
После того, как задача завершилась (End на экране), жмем Status
Статус = FINISHED. Задача завершена успешно, метод onPostExecute был выполнен.
Теперь посмотрим, какой статус будет если отменить задачу. Перепишем startTask:
private void startTask() {
mt = new MyTask();
mt.execute();
mt.cancel(false);
}
Недолго думая отменяем задачу сразу после запуска.
Сохраняем, запускаем приложение. Жмем Start.
Задача отменилась. Жмем Status
Статус почему-то RUNNING, как будто задача в работе. Не особо логично, конечно, но вот такая особенность реализации. Почему нельзя было ввести еще один статус CANCELED – я не знаю. Разработчикам Android виднее.
Как тогда отличить, задача запущена или отменена? Можно использовать метод isCancelled. Перепишем showStatus например так:
private void showStatus() {
if (mt != null)
if (mt.isCancelled())
Toast.makeText(this, "CANCELLED", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, mt.getStatus().toString(), Toast.LENGTH_SHORT).show();
}
Сохраняем, запускаем приложение. Жмем Start, задача отменяется. Жмем Status
Задача отменена, значит isCancelled вернул true, и мы вывели соответствующее сообщение.
На следующем уроке:
- сохраняем связь с AsyncTask при повороте экрана