Урок 90. AsyncTask. Status – статусы задачи
Урок 90. AsyncTask. Status – статусы задачи
В этом уроке:
- читаем статусы задачи
Click here to read this article!
- читаем статусы задачи
Click here to read this article!
Последний раз редактировалось damager82 20 май 2017, 20:12, всего редактировалось 4 раза.
Re: Урок 90. AsyncTask. Status – статусы задачи
Извините, что не по теме.. но у меня такая забавность) У меня на домашнем компе эклипс настоятельно требует убрать @Override в коде:
Иначе пишет, что в проекте ошиба.. Хотя коню понятно что это переопределённый метод.. Дело усугубляется тем, что с этим проектом я работаю юзая гитхаб.. с другого компа.. так вот на другом компе такой лажи не возникает.. В чём может быть дело!??!
Код: Выделить всё
public class ThreeActivity extends Activity implements OnClickListener{
...
@Override
public void onClick(View v) {
....
}
}
Re: Урок 90. AsyncTask. Status – статусы задачи
Буду кратокbrucemax писал(а):Извините, что не по теме.. но у меня такая забавность) У меня на домашнем компе эклипс настоятельно требует убрать @Override в коде:
Project->Properties, там находим Java Compiler и ставим Compiler compliance level 1.6 или выше
Re: Урок 90. AsyncTask. Status – статусы задачи
Спасибо, но краткость себя не оправдала=) Даже 1.7 пробывал.. таже проблема=)AndreyI писал(а):Буду кратокbrucemax писал(а):Извините, что не по теме.. но у меня такая забавность) У меня на домашнем компе эклипс настоятельно требует убрать @Override в коде:
Project->Properties, там находим Java Compiler и ставим Compiler compliance level 1.6 или выше
Re: Урок 90. AsyncTask. Status – статусы задачи
Ну тогда просто удалите метод, эклипс начнет ругаться на не переопределенные методы интерфейса, пересоздайте метод автоматом (add unimplemented methods), только уровень компилятора должен быть 1.6 или выше (если будет ниже, то метод будет создан без @Override).
Еще попробуйте "Android Tools" -> "Fix Project Properties"
Еще попробуйте "Android Tools" -> "Fix Project Properties"
Re: Урок 90. AsyncTask. Status – статусы задачи
Так эта проблема популярна.. viewtopic.php?f=3&t=117&p=149#p150 всё списываем на версии javaAndreyI писал(а):Ну тогда просто удалите метод, эклипс начнет ругаться на не переопределенные методы интерфейса, пересоздайте метод автоматом (add unimplemented methods), только уровень компилятора должен быть 1.6 или выше (если будет ниже, то метод будет создан без @Override).
Еще попробуйте "Android Tools" -> "Fix Project Properties"
Re: Урок 90. AsyncTask. Status – статусы задачи
Это, конечно, ни разу не принципиально, но так для сведения сообщу: тестирую на версии Android 4.1.2. при нажатии на кнопку Status после отмены, выдает результат FINISHED (супротив RUNNING в вашем случае).
Re: Урок 90. AsyncTask. Status – статусы задачи
Неплохо было б еще в уроках по AsyncTask осветить такие моменты, как executeOnExecutor, SERIAL_EXECUTOR и THREAD_POOL_EXECUTOR. Ну, это так, пожелание. Полдня убил, пытаясь заставить несколько асинктасков выполняться в порядке вызова, пока на SERIAL_EXECUTOR не набрел.
Re: Урок 90. AsyncTask. Status – статусы задачи
Добрый день!
Надеюсь тема ещё жива.
Не мог определиться, в ветку форума для какого урока поместить мой вопрос, потому продублировал его и в ветке 89 урока.
Хотел проверить работу AsyncTask совместно с Handler и Runnable и вошел в стопор. Суть моих двух проблем в ниже представленном коде такова:
[syntax=java5]package com.mytextproject.test;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private int myInteger = 0;
private boolean myBoolean = true;
private TextView txtResult;
private String startTag ="<html>";
private String endTag ="</html>";
private String title1 = "The variables from the main thread is set <b>via Increase Variable button</b>:";
private String title2 = "The variables from the main thread is set <b>via publishProgress() in the AsyncTask</b>:";
private MyAsyncTask TestTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView txt = (TextView)findViewById(R.id.maintextview);
txtResult = (TextView)findViewById(R.id.resulttextview);
txt.setText(Html.fromHtml(title1));
txtResult.setText(Html.fromHtml(title2));
//Меняем значения отображаемых переменных
Button myButtonIncreaseVariables = (Button)findViewById(R.id.increasevariables);
myButtonIncreaseVariables.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
++myInteger;
myBoolean=!myBoolean;
txt.setText(Html.fromHtml(startTag+title1+new String("<br>\tmyInteger="+myInteger+"<br>\tmyBoolean="+myBoolean)+endTag));
}
});
//Стартуем задачу
Button myButtonStart = (Button)findViewById(R.id.starttask);
myButtonStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(TestTask != null){
if( TestTask.CancelFlag == true )
{
TestTask = new MyAsyncTask();
Log.d("MY_TEST_MESSAGE","Before execution, getStatus()="+TestTask.getStatus().toString());
TestTask.execute();
Log.d("MY_TEST_MESSAGE","After the execution has been started, getStatus()="+TestTask.getStatus().toString());
}
}
else{
Log.d("MY_TEST_MESSAGE","TestTask=null");
TestTask = new MyAsyncTask();
Log.d("MY_TEST_MESSAGE","Before execution, getStatus()="+TestTask.getStatus().toString());
TestTask.execute();
Log.d("MY_TEST_MESSAGE","After the execution has been started, getStatus()="+TestTask.getStatus().toString());
}
}
});
//Завершаем задачу
Button myButtonStop = (Button)findViewById(R.id.stoptask);
myButtonStop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TestTask.cancel(false);
}
});
//Устанавливаем наш флаг, контролирующий завершение выполнения задачи
Button myButtonSetStopFlag = (Button)findViewById(R.id.setstopflag);
myButtonSetStopFlag.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TestTask.CancelFlag = true;
}
});
}
private class MyAsyncTask extends AsyncTask<Void,Void,Void>{
boolean CancelFlag = false;
Handler atHandler = new Handler();
Runnable atWorker = new Runnable(){
public void run() {
Log.d("MY_TEST_MESSAGE","atWorker still is working!");
printText();
};
};
void printText(){
if(!this.isCancelled() && !CancelFlag){
publishProgress();
atHandler.post(atWorker);
}
else{
atHandler.removeCallbacks(atWorker);
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
printText();
publishProgress();
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
txtResult.setText(Html.fromHtml(startTag+title2+new String("<br>\tmyInteger="+myInteger+"<br>\tmyBoolean="+myBoolean)+endTag));
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
publishProgress();
Toast.makeText(getApplicationContext(), "AsyncTask has been stopped by setting CancelFlag", 3000).show();
}
@Override
protected void onCancelled() {
super.onCancelled();
CancelFlag = true;
Log.d("MY_TEST_MESSAGE","CancelFlag="+CancelFlag);
}
}
}[/syntax]
main.xml:
[syntax=xml]<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/maintextview"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@drawable/back" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center" >
<Button
android:id="@+id/starttask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Task" />
<Button
android:id="@+id/stoptask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop Task" />
</LinearLayout>
<Button
android:id="@+id/setstopflag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Set Stop Flag" />
<Button
android:id="@+id/increasevariables"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Increase Variables" />
<TextView
android:id="@+id/resulttextview"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@drawable/back" />
</LinearLayout>[/syntax]
back.xml:
[syntax=xml]<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>[/syntax]
Буду благодарен любым ответам.
Надеюсь тема ещё жива.
Не мог определиться, в ветку форума для какого урока поместить мой вопрос, потому продублировал его и в ветке 89 урока.
Хотел проверить работу AsyncTask совместно с Handler и Runnable и вошел в стопор. Суть моих двух проблем в ниже представленном коде такова:
- Почему при запуске задачи на экран сразу же выводится моё Toast-сообщение из onPostExecuted() ("AsyncTask has been stopped by setting CancelFlag"), тогда как AsyncTask работу свою ещё не завершил (о чём говорит циклически выполняющийся Log.d("MY_TEST_MESSAGE","atWorker still is working!");)?
- Почему нет никакой реакции на вызов метода MyTask.cancel(false) и т.о. всё, что в onCancelled() не обрабатывается?
[syntax=java5]package com.mytextproject.test;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private int myInteger = 0;
private boolean myBoolean = true;
private TextView txtResult;
private String startTag ="<html>";
private String endTag ="</html>";
private String title1 = "The variables from the main thread is set <b>via Increase Variable button</b>:";
private String title2 = "The variables from the main thread is set <b>via publishProgress() in the AsyncTask</b>:";
private MyAsyncTask TestTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView txt = (TextView)findViewById(R.id.maintextview);
txtResult = (TextView)findViewById(R.id.resulttextview);
txt.setText(Html.fromHtml(title1));
txtResult.setText(Html.fromHtml(title2));
//Меняем значения отображаемых переменных
Button myButtonIncreaseVariables = (Button)findViewById(R.id.increasevariables);
myButtonIncreaseVariables.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
++myInteger;
myBoolean=!myBoolean;
txt.setText(Html.fromHtml(startTag+title1+new String("<br>\tmyInteger="+myInteger+"<br>\tmyBoolean="+myBoolean)+endTag));
}
});
//Стартуем задачу
Button myButtonStart = (Button)findViewById(R.id.starttask);
myButtonStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(TestTask != null){
if( TestTask.CancelFlag == true )
{
TestTask = new MyAsyncTask();
Log.d("MY_TEST_MESSAGE","Before execution, getStatus()="+TestTask.getStatus().toString());
TestTask.execute();
Log.d("MY_TEST_MESSAGE","After the execution has been started, getStatus()="+TestTask.getStatus().toString());
}
}
else{
Log.d("MY_TEST_MESSAGE","TestTask=null");
TestTask = new MyAsyncTask();
Log.d("MY_TEST_MESSAGE","Before execution, getStatus()="+TestTask.getStatus().toString());
TestTask.execute();
Log.d("MY_TEST_MESSAGE","After the execution has been started, getStatus()="+TestTask.getStatus().toString());
}
}
});
//Завершаем задачу
Button myButtonStop = (Button)findViewById(R.id.stoptask);
myButtonStop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TestTask.cancel(false);
}
});
//Устанавливаем наш флаг, контролирующий завершение выполнения задачи
Button myButtonSetStopFlag = (Button)findViewById(R.id.setstopflag);
myButtonSetStopFlag.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TestTask.CancelFlag = true;
}
});
}
private class MyAsyncTask extends AsyncTask<Void,Void,Void>{
boolean CancelFlag = false;
Handler atHandler = new Handler();
Runnable atWorker = new Runnable(){
public void run() {
Log.d("MY_TEST_MESSAGE","atWorker still is working!");
printText();
};
};
void printText(){
if(!this.isCancelled() && !CancelFlag){
publishProgress();
atHandler.post(atWorker);
}
else{
atHandler.removeCallbacks(atWorker);
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
printText();
publishProgress();
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
txtResult.setText(Html.fromHtml(startTag+title2+new String("<br>\tmyInteger="+myInteger+"<br>\tmyBoolean="+myBoolean)+endTag));
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
publishProgress();
Toast.makeText(getApplicationContext(), "AsyncTask has been stopped by setting CancelFlag", 3000).show();
}
@Override
protected void onCancelled() {
super.onCancelled();
CancelFlag = true;
Log.d("MY_TEST_MESSAGE","CancelFlag="+CancelFlag);
}
}
}[/syntax]
main.xml:
[syntax=xml]<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/maintextview"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@drawable/back" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center" >
<Button
android:id="@+id/starttask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Task" />
<Button
android:id="@+id/stoptask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop Task" />
</LinearLayout>
<Button
android:id="@+id/setstopflag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Set Stop Flag" />
<Button
android:id="@+id/increasevariables"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Increase Variables" />
<TextView
android:id="@+id/resulttextview"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@drawable/back" />
</LinearLayout>[/syntax]
back.xml:
[syntax=xml]<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#ffffff" />
<stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>[/syntax]
Буду благодарен любым ответам.
Re: Урок 90. AsyncTask. Status – статусы задачи
Посредством дебагинга я в принципе ответил на оба своих вопроса.
Однако, теперь не ясно где выполняется запущенное повторяющееся событие?
И, можно ли не беспокоиться об какой-либо утечке (не только в данном случае, но и для любого другого повторяющегося кода), когда стопирующий флаг CancelFlag принимает значение true для обрыва процесса повторения?
И со вторым вопросом остаётся неясность, почему на Android 2.3.3 ввиду немедленного завершения doInBackground() метод TextTask.cancel(false), как теперь понятно ожидаемо, возвращает false, а, например, на Android 4.2 хотя метод TextTask.cancel(false) и возвращает false и в onCancelled() мы не попадаем, но задача может быть остановлена не только через флаг CancelFlag, но и этим методом?
Т.е., после вызова TestTask.execute(); мы попадаем в doInBackground(), где входим в тело метода printText();, в котором, проверив выполнимость условий, инициируем onProgressUpdate(), затем отправляем сообщение на запуск atWorker, выходим из printText();, опять инициируем onProgressUpdate() и затем попадаем в onPostExecute(), после отработки которого, наша задача имеет статус FINISHED.EvilAngel писал(а):
- Почему при запуске задачи на экран сразу же выводится моё Toast-сообщение из onPostExecuted() ("AsyncTask has been stopped by setting CancelFlag"), тогда как AsyncTask работу свою ещё не завершил (о чём говорит циклически выполняющийся Log.d("MY_TEST_MESSAGE","atWorker still is working!");)?
- Почему нет никакой реакции на вызов метода MyTask.cancel(false) и т.о. всё, что в onCancelled() не обрабатывается?
Однако, теперь не ясно где выполняется запущенное повторяющееся событие?
И, можно ли не беспокоиться об какой-либо утечке (не только в данном случае, но и для любого другого повторяющегося кода), когда стопирующий флаг CancelFlag принимает значение true для обрыва процесса повторения?
И со вторым вопросом остаётся неясность, почему на Android 2.3.3 ввиду немедленного завершения doInBackground() метод TextTask.cancel(false), как теперь понятно ожидаемо, возвращает false, а, например, на Android 4.2 хотя метод TextTask.cancel(false) и возвращает false и в onCancelled() мы не попадаем, но задача может быть остановлена не только через флаг CancelFlag, но и этим методом?
Re: Урок 90. AsyncTask. Status – статусы задачи
Если честно, мне не совсем понятна логика... но сразу, что бросается в глаза - publishProgress()(в документации написано - protected final void publishProgress (Progress... values)), т.е. нужно передать int в метод... Это конечно может быть причиной, но почему то мне кажется, что если посмотреть log, многое станет понятно...EvilAngel писал(а):Добрый день!
Надеюсь тема ещё жива.
Не мог определиться, в ветку форума для какого урока поместить мой вопрос, потому продублировал его и в ветке 89 урока.
Хотел проверить работу AsyncTask совместно с Handler и Runnable и вошел в стопор. Суть моих двух проблем в ниже представленном коде такова:Буду благодарен любым ответам.
- Почему при запуске задачи на экран сразу же выводится моё Toast-сообщение из onPostExecuted() ("AsyncTask has been stopped by setting CancelFlag"), тогда как AsyncTask работу свою ещё не завершил (о чём говорит циклически выполняющийся Log.d("MY_TEST_MESSAGE","atWorker still is working!");)?
- Почему нет никакой реакции на вызов метода MyTask.cancel(false) и т.о. всё, что в onCancelled() не обрабатывается?
А по поводу второго вопроса я вообще завис... onCancelled() вызывается после отработки cancel() при условии, что возвращается значение true(опять же из доков), судя по тому, что пишете вы - насильно передаете false? т.е. таск завершается нормально и соответсвенно onCancelled() не вызывается вообще.
P.S. если честно я вообще не понимаю вашего кода, потому может пишу что -то не так. Но то, что сделал бы я - в корне изменил логику... тут есть уроки показывающие, как решается ваша задача.
Re: Урок 90. AsyncTask. Status – статусы задачи
EvilAngel писал(а):Посредством дебагинга я в принципе ответил на оба своих вопроса.Т.е., после вызова TestTask.execute(); мы попадаем в doInBackground(), где входим в тело метода printText();, в котором, проверив выполнимость условий, инициируем onProgressUpdate(), затем отправляем сообщение на запуск atWorker, выходим из printText();, опять инициируем onProgressUpdate() и затем попадаем в onPostExecute(), после отработки которого, наша задача имеет статус FINISHED.EvilAngel писал(а):
- Почему при запуске задачи на экран сразу же выводится моё Toast-сообщение из onPostExecuted() ("AsyncTask has been stopped by setting CancelFlag"), тогда как AsyncTask работу свою ещё не завершил (о чём говорит циклически выполняющийся Log.d("MY_TEST_MESSAGE","atWorker still is working!");)?
- Почему нет никакой реакции на вызов метода MyTask.cancel(false) и т.о. всё, что в onCancelled() не обрабатывается?
Однако, теперь не ясно где выполняется запущенное повторяющееся событие?
И, можно ли не беспокоиться об какой-либо утечке (не только в данном случае, но и для любого другого повторяющегося кода), когда стопирующий флаг CancelFlag принимает значение true для обрыва процесса повторения?
И со вторым вопросом остаётся неясность, почему на Android 2.3.3 ввиду немедленного завершения doInBackground() метод TextTask.cancel(false), как теперь понятно ожидаемо, возвращает false, а, например, на Android 4.2 хотя метод TextTask.cancel(false) и возвращает false и в onCancelled() мы не попадаем, но задача может быть остановлена не только через флаг CancelFlag, но и этим методом?
не дочитал - но сразу вопрос - onProgressUpdate() , я не увидел в вашем коде такого метода.... ваш метод printText вызывает publishProgress() при чем не передавая параметры.. если честно после второго комментария я вас еще хуже понимать стал))
Точно так же не понял где Runnable, который вы хотели попробовать и вообще что вы делаете... для начала думаю стоит описать цель,поскольку метод, которым вы идете явно не много не туда вас повел. Но вообще ответ прост onPostExecute вызывается после doInBackground, который завершил работу(а он ее завершил, но явно не так, как вы ожидали)).. нужно смотреть логи - уверен, там есть ответ.
Re: Урок 90. AsyncTask. Status – статусы задачи
Первое, что хотелось бы отметить - Спасибо большое за комментарии!
Теперь:
если внимательно присмотреться на сигнатуру метода, то она такова:[syntax=java5]protected final void publishProgress(Progress... values)[/syntax]т.е. данный метод принимает переменное число параметров и таких параметров может не быть вовсе (из определения методов с переменным числом аргументов).
Если обратиться к документации:
Далее,
И, наконец.
Теперь:
Насчет publishProgress():altwin писал(а): Если честно, мне не совсем понятна логика... но сразу, что бросается в глаза - publishProgress()(в документации написано - protected final void publishProgress (Progress... values)), т.е. нужно передать int в метод... Это конечно может быть причиной, но почему то мне кажется, что если посмотреть log, многое станет понятно...
если внимательно присмотреться на сигнатуру метода, то она такова:[syntax=java5]protected final void publishProgress(Progress... values)[/syntax]т.е. данный метод принимает переменное число параметров и таких параметров может не быть вовсе (из определения методов с переменным числом аргументов).
Если обратиться к документации:
что никак НЕ ограничивает тип данных прогресса выполнения задачи только типом int.Progress, the type of the progress units published during the background computation.
Далее,
В метод cancel() я передаю false, руководствуясь вполне резонным замечанием автора статьи. Во втором моём комментарии я попытался, пошагово следуя своим изысканиям, ответить на свой же вопрос "почему?"altwin писал(а): А по поводу второго вопроса я вообще завис... onCancelled() вызывается после отработки cancel() при условии, что возвращается значение true(опять же из доков), судя по тому, что пишете вы - насильно передаете false? т.е. таск завершается нормально и соответсвенно onCancelled() не вызывается вообще.
И, наконец.
Собственно задачей я поставил перед собой исследовать такое взаимодействие трёх составляющих AsyncTask-Handler-Runnable, чтобы не прибегать к помощи циклов for или while, когда длительные повторяющиеся действия выносятся в отдельный поток.altwin писал(а): P.S. если честно я вообще не понимаю вашего кода, потому может пишу что -то не так. Но то, что сделал бы я - в корне изменил логику... тут есть уроки показывающие, как решается ваша задача.
Последний раз редактировалось EvilAngel 10 дек 2013, 02:11, всего редактировалось 1 раз.
Re: Урок 90. AsyncTask. Status – статусы задачи
onProgressUpdate() - третий метод с конца моего листинга (о publishProgress() я отписался выше).altwin писал(а):не дочитал - но сразу вопрос - onProgressUpdate() , я не увидел в вашем коде такого метода.... ваш метод printText вызывает publishProgress() при чем не передавая параметры..
просто в первом абзаце моего второго комментария, пошагово пробегая строки кода, я изложил свой ответ себе на "почему?"altwin писал(а):если честно после второго комментария я вас еще хуже понимать стал))
Runnable также присутствует в листинге и является частью моего класса MyAsyncTask:[syntax=java5]private class MyAsyncTask extends AsyncTask<Void,Void,Void>{altwin писал(а):Точно так же не понял где Runnable, который вы хотели попробовать и вообще что вы делаете... для начала думаю стоит описать цель,поскольку метод, которым вы идете явно не много не туда вас повел. Но вообще ответ прост onPostExecute вызывается после doInBackground, который завершил работу(а он ее завершил, но явно не так, как вы ожидали)).. нужно смотреть логи - уверен, там есть ответ.
boolean CancelFlag = false;
Handler atHandler = new Handler();
Runnable atWorker = new Runnable(){
public void run() {
Log.d("MY_TEST_MESSAGE","atWorker still is working!");
printText();
};
};[/syntax]
Re: Урок 90. AsyncTask. Status – статусы задачи
Чтобы избавить Вас от изучения кода и попытки понять, что я имел ввиду, попытаюсь сконцентрировать внимание на том, что мне не ясно в данный конкретный момент:
Учитывая, что в методе doInBackground() я вызываю дополнительный метод printText(), в котором инициирую запуск Runnable, вызывающего этот же метод printText() и завершающегося при условии установки флага CancelFlag=true, получается, что doInBackground() не будет ждать когда завершится Runnable, и практически сразу получит управление из printText(), благополучно завершив свою работу и передав управление в onPostExecute(). А это значит, что задача получит статус ЗАВЕРШЕНА. При этом где-то в памяти будет продолжаться работа моего Runnable. Потому я и задал вопросы: где теперь выполняется запущенное повторяющееся событие и насколько потенциальна утечка памяти?
И, наконец, последнее. Т.к. doInBackground() не ожидает завершения запущенного Runnable, как это было бы, например, с while(...){...} (если, конечно, я правильно оценил свои наблюдения), то я ожидал, что TestTask.cancel(false) вернёт false и onCancelled() не будет достигнут. Так оно и произошло за исключением непонятного мне момента: на Android 2.3.3 TestTask.cancel(false) ни к чему не привел, тогда как на Android 4.2 хотя метод TextTask.cancel(false) и возвращает false и в onCancelled() мы не попадаем, но запущенный Runnable благополучно остановился.
Учитывая, что в методе doInBackground() я вызываю дополнительный метод printText(), в котором инициирую запуск Runnable, вызывающего этот же метод printText() и завершающегося при условии установки флага CancelFlag=true, получается, что doInBackground() не будет ждать когда завершится Runnable, и практически сразу получит управление из printText(), благополучно завершив свою работу и передав управление в onPostExecute(). А это значит, что задача получит статус ЗАВЕРШЕНА. При этом где-то в памяти будет продолжаться работа моего Runnable. Потому я и задал вопросы: где теперь выполняется запущенное повторяющееся событие и насколько потенциальна утечка памяти?
И, наконец, последнее. Т.к. doInBackground() не ожидает завершения запущенного Runnable, как это было бы, например, с while(...){...} (если, конечно, я правильно оценил свои наблюдения), то я ожидал, что TestTask.cancel(false) вернёт false и onCancelled() не будет достигнут. Так оно и произошло за исключением непонятного мне момента: на Android 2.3.3 TestTask.cancel(false) ни к чему не привел, тогда как на Android 4.2 хотя метод TextTask.cancel(false) и возвращает false и в onCancelled() мы не попадаем, но запущенный Runnable благополучно остановился.
Re: Урок 90. AsyncTask. Status – статусы задачи
не стоит полагаться на то, что ваш метод дождется окончания выполнения потока -по этому поводу четко сказано в документации java, поток не имеет четкого времени выполнения, в отличии от приведенного вами цикла. если хотите дождаться выполнения операции, то нужно выполнять синхронизацию, лучше для безопастности потоков лочить данные, вариантов много. То, что где то у вас получилось выполнить - говорит только о том, что приложение простое и запускали вы его не часто, когда основной код выполняется в main потоке, в котором вы запускаете второй, никто не гарантирует, что вы дождетесь завершения(нужна явная синхронизация), для примера можете просто сделать sleep() в doInBackground на несколько секунд и тогда скорее всего получите то, что хотите(методу придется дождаться), но это не решение. Лучше всего реализовать interface Lock на данных которые используются в потоке, и не выполнять к примеру publishProgress() до тех пор, пока данные из printText() не станут доступны. Таким образом doInBackground завершится только после получения... Не уверен, что правильно все сказал.. поскольку мне вообще трудно делать выводы о коде в котором столько Void классов... мне вообще не ясно зачем это делать, но думаю суть понятна. Либо синхронизировать, либо, что более потоко - безопастно ставить Lock.EvilAngel писал(а):Чтобы избавить Вас от изучения кода и попытки понять, что я имел ввиду, попытаюсь сконцентрировать внимание на том, что мне не ясно в данный конкретный момент:
Учитывая, что в методе doInBackground() я вызываю дополнительный метод printText(), в котором инициирую запуск Runnable, вызывающего этот же метод printText() и завершающегося при условии установки флага CancelFlag=true, получается, что doInBackground() не будет ждать когда завершится Runnable, и практически сразу получит управление из printText(), благополучно завершив свою работу и передав управление в onPostExecute(). А это значит, что задача получит статус ЗАВЕРШЕНА. При этом где-то в памяти будет продолжаться работа моего Runnable. Потому я и задал вопросы: где теперь выполняется запущенное повторяющееся событие и насколько потенциальна утечка памяти?
И, наконец, последнее. Т.к. doInBackground() не ожидает завершения запущенного Runnable, как это было бы, например, с while(...){...} (если, конечно, я правильно оценил свои наблюдения), то я ожидал, что TestTask.cancel(false) вернёт false и onCancelled() не будет достигнут. Так оно и произошло за исключением непонятного мне момента: на Android 2.3.3 TestTask.cancel(false) ни к чему не привел, тогда как на Android 4.2 хотя метод TextTask.cancel(false) и возвращает false и в onCancelled() мы не попадаем, но запущенный Runnable благополучно остановился.
P.S. опять же всю логику printText можно вынести в отдельный класс реализующий Callable<>, и выполнять запуск с помощью ExecutorService, тогда поток сможет возвращать какие -то данные, после получения которых продолжать выполнение...
-
- Сообщения: 42
- Зарегистрирован: 25 янв 2015, 18:57
Re: Урок 90. AsyncTask. Status – статусы задачи
На счет того момента, что getStatus возвращает RUNNING, когда задача отменена. В вервии Android выше 4 и выше походу дела изменилось-теперь возвращает FINISHED
-
- Сообщения: 9
- Зарегистрирован: 15 окт 2015, 15:14
Re: Урок 90. AsyncTask. Status – статусы задачи
Здравствуйте, извините если не в той ветки вопрос, не нашел нужную, помогите новичку пожалуйста. У меня в AsynTask выполняется парсинг XML страницы, все работает, в главной активности есть массив с которым я хочу дальше работать в MainActivity. Мне нужно чтобы после того как завершиться парсинг XML страницы в AsynTask, этот массив заполнился данными из AsynTask, побывал метод get, но в логах выдает, что массив пустой. Может надо как то настроить postExecut правильно, или правильно объявить массив в MainActivity, но пока в голову не чего не приходит. Спасибо за любой совет.
-
- Сообщения: 9
- Зарегистрирован: 15 окт 2015, 15:14
Re: Урок 90. AsyncTask. Status – статусы задачи
Подскажите пожалуйста почему эта строчка не работает if (downloadXmlTask.getStatus().toString().equals("FINISHED")) ? Или как сказать программе чтобы она не выполнялась пока AsynTask не закончит работу ?
Re: Урок 90. AsyncTask. Status – статусы задачи
асинктаск может "сказать программе" когда завершится, по-другому никак. Читай урок повнимательнее - там есть место, где понятно, что асинктаск закончил работу.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198