Когда я вызываю cancel(false)
, чтобы остановить мой ASyncTask
, я обнаруживаю, что функция onCancelled()
вызывается еще до того, как я смог обнаружить, что задача отменяется в doInBackground()
с использованием isCancelled()
.
Я пытался изменить аргумент функции отмены на true, но это тоже не помогло.
Когда я прочитал документацию, я понял, что смогу обнаружить отмену в doInBackground()
, вернитесь из этой функции и только после того, как вместо onPostExecute()
.
* 1014 будет вызвана функция
onCancelled()
. Я что-то упустил?Нужно ли добавлять дополнительные механизмы синхронизации, чтобы все происходило в том порядке, в котором я ожидаю?
РЕДАКТИРОВАТЬ:
Вот как организован код:
AsyncTask<Void,Integer,Void>() {
ProgressDialog mProgressDialog;
@Override
protected Void doInBackground(Void... voids) {
for (int i=0; i<size; i++) {
publishProgress(i/100);
if (isCancelled()) {
Log.d(TAG, "getting out");
return null;
}
// do some database operations here
}
// do some house cleaning work also here
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// create the progress dialog if needed
mProgressDialog = new ProgressDialog(context);
mProgressDialog.setMessage("Do it!");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialogInterface) {
cancel(false);
}
});
mProgressDialog.setCancelable(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
// create some database here
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mProgressDialog.setProgress(values[0]);
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mProgressDialog.dismiss();
}
@Override
protected void onCancelled() {
super.onCancelled();
Log.d(TAG, "Cancelling !");
// since we are cancelling the operation, close and delete the database that was being created
mProgressDialog.dismiss();
}
}
Таким образом, проблема заключается в том, что в настоящий момент все еще выполняются некоторые операции с базой данных, даже если она удаляется в onCancelled()
.Симптом заключается в том, что порядок сообщений «вылезает» и «отменяется!»не согласуется (и я сделал это также с отладчиком, похоже, что вызов cancel()
переходит непосредственно к onCancelled()
, пока другой поток все еще работает.
Одной из возможных причин может быть этосообщение Я только что нашел ...? (я запускаю это на Froyo)
БОЛЬШЕ ...
Хотя я установил флаг в вызове cancel()
как ложный, яобнаружите, что функция doInBackground()
не имеет возможности завершить или обнаружить отмену (она даже не доходит до оператора return)