Урок 89. AsyncTask. Cancel – отменяем задачу в процессе выполнения
Урок 89. AsyncTask. Cancel – отменяем задачу в процессе выполнения
В этом уроке:
- отменяем задачу в процессе выполнения
Click here to read this article!
- отменяем задачу в процессе выполнения
Click here to read this article!
Последний раз редактировалось damager82 20 май 2017, 20:11, всего редактировалось 5 раз.
-
- Сообщения: 4
- Зарегистрирован: 29 июн 2012, 03:14
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Здравствуйте.
Хочу внести ясность в этот кусок текста:
В документации видим два метода:
onCancelled() - This method is invoked by the default implementation of onCancelled(Object)
onCancelled(Object) - Runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished.
The default implementation simply invokes onCancelled() and ignores the result. If you write your own implementation, do not call super.onCancelled(result).
Иными словами, onCancelled(Object) вызывамется вместо onPostExecute(Object) если был вызван метод отмены. А onCancelled() - лишь дефолтное поведение метода onCancelled(Object). К слову добавим, что параметр - это результат работы doInBackground, как и в onPostExecute.
Проверяем нашу догадку. Чуть модифицируем ваш код:
Т.е. мы оставили дефолтное поведение метода onCancelled(Void), но отслеживаем его начало и конец выполнения.
Смотрим, что получается:
Хочу внести ясность в этот кусок текста:
Не знаю, как так получилось. Потому что, если запустить на четвёртом Андроиде, то будет так:08:17:51.956: D/myLogs(487): Begin
08:17:52.993: D/myLogs(487): isCancelled: false
08:17:53.998: D/myLogs(487): isCancelled: false
08:17:54.543: D/myLogs(487): cancel result: true
08:17:54.552: D/myLogs(487): Cancel
08:17:55.042: D/myLogs(487): isCancelled: true
08:17:56.061: D/myLogs(487): isCancelled: true
08:17:57.111: D/myLogs(487): isCancelled: true
Разберёмся, почему так и должно быть.07-15 09:33:23.548: D/myLogs(5474): Begin
07-15 09:33:24.569: D/myLogs(5474): isCancelled: false
07-15 09:33:24.869: D/myLogs(5474): cancel result: true
07-15 09:33:25.570: D/myLogs(5474): isCancelled: true
07-15 09:33:26.581: D/myLogs(5474): isCancelled: true
07-15 09:33:27.582: D/myLogs(5474): isCancelled: true
07-15 09:33:28.583: D/myLogs(5474): isCancelled: true
07-15 09:33:28.583: D/myLogs(5474): Cancel
В документации видим два метода:
onCancelled() - This method is invoked by the default implementation of onCancelled(Object)
onCancelled(Object) - Runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished.
The default implementation simply invokes onCancelled() and ignores the result. If you write your own implementation, do not call super.onCancelled(result).
Иными словами, onCancelled(Object) вызывамется вместо onPostExecute(Object) если был вызван метод отмены. А onCancelled() - лишь дефолтное поведение метода onCancelled(Object). К слову добавим, что параметр - это результат работы doInBackground, как и в onPostExecute.
Проверяем нашу догадку. Чуть модифицируем ваш код:
Код: Выделить всё
@Override
protected void onCancelled (Void result)
{
Log.d(LOG_TAG, "onCancelled(Void) start");
super.onCancelled(result);
Log.d(LOG_TAG, "onCancelled(Void) finish");
}
@Override
protected void onCancelled()
{
super.onCancelled();
tvInfo.setText("Cancel");
Log.d(LOG_TAG, "Cancel");
}
Смотрим, что получается:
Видим, что родительский метод super.onCancelled(Void) вызывает наш метод onCancelled(), т.е. ведёт себя ровно так, как написано в документации.07-15 09:47:04.509: D/myLogs(6027): Begin
07-15 09:47:05.530: D/myLogs(6027): isCancelled: false
07-15 09:47:06.541: D/myLogs(6027): isCancelled: false
07-15 09:47:07.342: D/myLogs(6027): cancel result: true
07-15 09:47:07.542: D/myLogs(6027): isCancelled: true
07-15 09:47:08.543: D/myLogs(6027): isCancelled: true
07-15 09:47:09.554: D/myLogs(6027): isCancelled: true
07-15 09:47:09.554: D/myLogs(6027): onCancelled(Void) start
07-15 09:47:09.554: D/myLogs(6027): Cancel
07-15 09:47:09.554: D/myLogs(6027): onCancelled(Void) finish
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Я запускал на Android 2.3.3. Значит, переписали они AsyncTask в новых версиях.
Спасибо за инфу! Попробую как-нить отметить этот нюанс в уроке.
Спасибо за инфу! Попробую как-нить отметить этот нюанс в уроке.
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Добрый день!
Надеюсь тема ещё жива.
Не мог определиться, в ветку форума для какого урока поместить мой вопрос, потому продублировал его и в ветке 90 урока.
Хотел проверить работу 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]
Буду благодарен любым ответам.
Надеюсь тема ещё жива.
Не мог определиться, в ветку форума для какого урока поместить мой вопрос, потому продублировал его и в ветке 90 урока.
Хотел проверить работу 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: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Посредством дебагинга я в принципе ответил на оба своих вопроса.
Однако, теперь не ясно где выполняется запущенное повторяющееся событие?
И, можно ли не беспокоиться об какой-либо утечке (не только в данном случае, но и для любого другого повторяющегося кода), когда стопирующий флаг 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: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
уже отвечал в теме, которую вы дублируете, но наверно стоит повторить, что нет в вашем коде onProgressUpdate() о котором вы пишете во втором сообщении. И из того, что вы говорите не понятно ничего - лучше покажите что выводится в консоль при компиляции.... и желательно в какую -то одну тему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, но и этим методом?
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Он есть - третьим методом с конца листинга (в теме к 90-ому уроку я расписал).altwin писал(а):уже отвечал в теме, которую вы дублируете, но наверно стоит повторить, что нет в вашем коде onProgressUpdate() о котором вы пишете во втором сообщении. И из того, что вы говорите не понятно ничего - лучше покажите что выводится в консоль при компиляции.... и желательно в какую -то одну тему
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Здравствуйте! Спасибо за уроки, очень точно и понятно все описано)
Появился вопрос. Допустим, в doInBackground выполняется всего один метод из внешней библиотеки. Как в таком случае его прервать, по-логике такие моменты должны были быть предусмотрены? Или я не прав?
Появился вопрос. Допустим, в doInBackground выполняется всего один метод из внешней библиотеки. Как в таком случае его прервать, по-логике такие моменты должны были быть предусмотрены? Или я не прав?
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Если внешний метод поддерживает остановку по interrupt, то он остановится при cancel(true). А если не поддерживает, то, думаю, что никак.ShamanDS писал(а):Здравствуйте! Спасибо за уроки, очень точно и понятно все описано)
Появился вопрос. Допустим, в doInBackground выполняется всего один метод из внешней библиотеки. Как в таком случае его прервать, по-логике такие моменты должны были быть предусмотрены? Или я не прав?
-
- Сообщения: 11
- Зарегистрирован: 29 янв 2013, 15:14
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Есть проблема
[syntax=java5]
static class blueServer
{
public static void setup()
{
// запуск сервера (ожидание подключения)
try
{
Log.d(TAG, myAdapter.getScanMode() == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE? "Connectable|Discoverable" : "Unconnectable");
acceptServerThread = new AsyncTask<Void, Void, Void>()
{
BluetoothServerSocket btserver = myAdapter.listenUsingRfcommWithServiceRecord("AppToServer", uuid);
BluetoothSocket serverSocket;
@Override
protected Void doInBackground(Void... params)
{
try
{
Log.d(TAG, "MakeBluetoothConnection: onResume() : Server accepting");
serverSocket = btserver.accept();
Log.d(TAG, "MakeBluetoothConnection: onResume() : Server accepted, starting activity");
Socket = serverSocket;
//Intent intent = new Intent(MakeBluetoothConnection.this, AppsActivity.class);
//startActivity(intent);
} catch (IOException e)
{
Log.d(TAG, "Accept connection error: " + e.getMessage());
}
return null;
}
@Override
protected void onCancelled()
{
Log.d(TAG, "MakeBluetoothConnection: onResume() : Cancel accepting");
if(!serverSocket.isConnected())
try
{
serverSocket.close();
btserver.close();
}
catch (IOException e)
{
Log.d(TAG, "MakeBluetoothConnection: onResume() : Cancel accepting error : " + e.getMessage());
}
}
};
acceptServerThread.execute();
}
catch(IOException e)
{
Log.d(TAG, "Server starting error: " + e.getMessage());
}
}
public static void stop()
{
if(!acceptServerThread.isCancelled() && acceptServerThread != null) acceptServerThread.cancel(false);
}
}
[/syntax]
Вызываю close с аргументом true, потому что постоянно проверять isCancelled не могу, так как btserver.accept() вешает поток. Поток в таком случае не прерывается. Как поступить в этой ситуации?
Может создать Thread для проверки?
[syntax=java5]
static class blueServer
{
public static void setup()
{
// запуск сервера (ожидание подключения)
try
{
Log.d(TAG, myAdapter.getScanMode() == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE? "Connectable|Discoverable" : "Unconnectable");
acceptServerThread = new AsyncTask<Void, Void, Void>()
{
BluetoothServerSocket btserver = myAdapter.listenUsingRfcommWithServiceRecord("AppToServer", uuid);
BluetoothSocket serverSocket;
@Override
protected Void doInBackground(Void... params)
{
try
{
Log.d(TAG, "MakeBluetoothConnection: onResume() : Server accepting");
serverSocket = btserver.accept();
Log.d(TAG, "MakeBluetoothConnection: onResume() : Server accepted, starting activity");
Socket = serverSocket;
//Intent intent = new Intent(MakeBluetoothConnection.this, AppsActivity.class);
//startActivity(intent);
} catch (IOException e)
{
Log.d(TAG, "Accept connection error: " + e.getMessage());
}
return null;
}
@Override
protected void onCancelled()
{
Log.d(TAG, "MakeBluetoothConnection: onResume() : Cancel accepting");
if(!serverSocket.isConnected())
try
{
serverSocket.close();
btserver.close();
}
catch (IOException e)
{
Log.d(TAG, "MakeBluetoothConnection: onResume() : Cancel accepting error : " + e.getMessage());
}
}
};
acceptServerThread.execute();
}
catch(IOException e)
{
Log.d(TAG, "Server starting error: " + e.getMessage());
}
}
public static void stop()
{
if(!acceptServerThread.isCancelled() && acceptServerThread != null) acceptServerThread.cancel(false);
}
}
[/syntax]
Вызываю close с аргументом true, потому что постоянно проверять isCancelled не могу, так как btserver.accept() вешает поток. Поток в таком случае не прерывается. Как поступить в этой ситуации?
Может создать Thread для проверки?
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Статья о темной стороне AsynckTask http://emunix.org/posts/the-dark-side-of-asynctask/
Лично я перешел на либу Volley и не знаю проблем http://arnab.ch/blog/2013/08/asynchrono ... ng-volley/
Лично я перешел на либу Volley и не знаю проблем http://arnab.ch/blog/2013/08/asynchrono ... ng-volley/
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Проблема не в AsynckTask, нечего на него гнать.
Проблема в BluetoothServerSocket. btserver.accept() нельзя прервать остановкой потока. Нужно вызывать close().
Должно помочь добавление следующего метода в AsynckTask:
[syntax=java]public void cancelAndCloseSocket() {
cancel();
btserver.close();
}[/syntax]
Естественно, безымянным классом AsynckTask, как в вашем коде, так не сделать. Нужно будет описывать свой класс MyAsynckTask и в него добавлять этот метод.
Проблема в BluetoothServerSocket. btserver.accept() нельзя прервать остановкой потока. Нужно вызывать close().
Должно помочь добавление следующего метода в AsynckTask:
[syntax=java]public void cancelAndCloseSocket() {
cancel();
btserver.close();
}[/syntax]
Естественно, безымянным классом AsynckTask, как в вашем коде, так не сделать. Нужно будет описывать свой класс MyAsynckTask и в него добавлять этот метод.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Я просто код не читал, увидел только про отмену работы AsynckTask и предположил что речь идет про сеть =)
- FastRus1804
- Сообщения: 49
- Зарегистрирован: 22 июн 2014, 11:20
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
А можно не отменить, а поставить на паузу AsynckTask ?
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Можно поставить на паузу поток, что его выполняет. Сделать это можно одним из способов:FastRus1804 писал(а):А можно не отменить, а поставить на паузу AsynckTask ?
1) Thread.sleep(1000);
2) someObject.wait();
Как этим пользоваться читайте в любой книге по Java, глава про потоки.
Только учтите, остановка потока может повлиять на работу остальных AsynckTask-ов.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Вот не надо так делать никогда с асинкТасками
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Я иногда так делаю. Только нужно понимать к чему это может привести. Об этом я предупредил .Mikhail_dev писал(а):Вот не надо так делать никогда с асинкТасками
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Это может привести не только к тому, а к паузе потока, откуда этот асинкТаск вызывается, а это обычно UI поток.
- FastRus1804
- Сообщения: 49
- Зарегистрирован: 22 июн 2014, 11:20
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
А почему так происходит?Mikhail_dev писал(а):Это может привести не только к тому, а к паузе потока, откуда этот асинкТаск вызывается, а это обычно UI поток.
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 89. AsyncTask. Cancel – отменяем задачу в процессе
Это случится если его так остановить в любом другом методе отличном от doInBackground. Если останавливать в doInBackground, максимум, что может произойти, остановка очереди, в результате чего остальные таски не запустятся пока этот не завершит свою работу.Mikhail_dev писал(а):Это может привести не только к тому, а к паузе потока, откуда этот асинкТаск вызывается, а это обычно UI поток.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.