Android 如果异步任务被取消,您要做些什么?
我正在使用AsyncTask填充SQLite数据库。我正在从某个网页下载数据并将其放入SQLite表中。问题是,我想要么下载100%的数据,要么不下载。因此,如果AsyncTask由于某种原因被中断,我希望删除迄今为止已下载的所有数据 我就是这样做的:Android 如果异步任务被取消,您要做些什么?,android,sqlite,android-asynctask,android-sqlite,Android,Sqlite,Android Asynctask,Android Sqlite,我正在使用AsyncTask填充SQLite数据库。我正在从某个网页下载数据并将其放入SQLite表中。问题是,我想要么下载100%的数据,要么不下载。因此,如果AsyncTask由于某种原因被中断,我希望删除迄今为止已下载的所有数据 我就是这样做的: @Override protected void onCancelled() { super.onCancelled(); dbHandler.deleteFromDatabase(razred); Log.i("TAG"
@Override
protected void onCancelled() {
super.onCancelled();
dbHandler.deleteFromDatabase(razred);
Log.i("TAG", "AsyncTask cancelled");
}
我认为,如果AsyncTask以任何方式被中断,onCancelled将执行,但事实并非如此。在以任何方式取消AsyncTask时,如何擦除使用AsyncTask生成的数据?例如,活动暂停、活动破坏、互联网连接中断等。您的做法是正确的,但在您的doInBackground中,您还需要特别致电isCancelled,检查是否取消,然后从doInBackground返回。那么你的代码就可以正常工作了 有关取消任务的信息,请参阅 以下是文档中的引用,以便于参考: 可以通过调用cancelboolean随时取消任务。调用此方法将导致对isCancelled的后续调用返回true。调用此方法后,将在doInBackgroundObject[]返回后调用onCancelledObject,而不是onPostExecuteObject。为了确保尽快取消任务,您应该始终从doInBackgroundObject[]定期检查isCancelled的返回值,如果可能的话,例如在循环中 编辑:根据请求,一些示例代码:
private class MyAsyncTask extends AsyncTask<Void,Void,Void> {
private SQLiteDatabase db;
@Override
protected void onPreExecute() {
// any kind of initialization or setup needed before the
// background thread kicks off. remember: this is still on
// on the main (UI) thread
// since youre doing DB I/O, Ill make believe Im initializing the DB here
db = DatabaseHelper.getInstance(MainActvity.this).getWritableDatabase();
}
/*
* The background thread to do your disk and network I/O. If you need
* to pass in any parameters, this is the first Void in the template
*/
@Override
protected Void doInBackground(Void... params) {
// other stuff you need to do in the background. Since you want an
// all-or-nothing type thing, we will use a transaction to manually
// control the db
db.beginTransaction();
try {
// do network I/O to retrieve what you need and then write to DB.
...
... // if theres a loop in here somewhere when reading the data, check !isCancelled() as part of the condition or as one of the first statements and then break
...
db.setTransactionSuccessful(); // assuming everything works, need to set
// this successful here at the end of the try
} catch (InterruptedException ie) { // or some other exception
cancel(true); // heres where you can call cancel() if youve been interrupted
} catch (IOException ioe) { // if your network connection has problems
cancel(true);
} finally {
db.endTransaction();
// other cleanup, like closing the HTTP connection...
// no need to close the DB if you implement it properly
}
return null; // if there was some return value, that would go here
}
@Override
protected void onCancelled(Void result) {
// depending on how you implement doInBackground(), you may not even need this,
// unless you have a lot of other "state" you need to reset aside from the DB transaction
}
@Override
protected void onPostExecute(Void result) {
// any other items to do on main (UI) thread after doInBackground() finishes
// remember, this only gets called if cancel() is not called!
}
}
希望有帮助 您走的是正确的道路,但在您的doInBackground中,您还需要专门致电isCancelled,检查它是否已取消,然后从doInBackground返回。那么你的代码就可以正常工作了 有关取消任务的信息,请参阅 以下是文档中的引用,以便于参考: 可以通过调用cancelboolean随时取消任务。调用此方法将导致对isCancelled的后续调用返回true。调用此方法后,将在doInBackgroundObject[]返回后调用onCancelledObject,而不是onPostExecuteObject。为了确保尽快取消任务,您应该始终从doInBackgroundObject[]定期检查isCancelled的返回值,如果可能的话,例如在循环中 编辑:根据请求,一些示例代码:
private class MyAsyncTask extends AsyncTask<Void,Void,Void> {
private SQLiteDatabase db;
@Override
protected void onPreExecute() {
// any kind of initialization or setup needed before the
// background thread kicks off. remember: this is still on
// on the main (UI) thread
// since youre doing DB I/O, Ill make believe Im initializing the DB here
db = DatabaseHelper.getInstance(MainActvity.this).getWritableDatabase();
}
/*
* The background thread to do your disk and network I/O. If you need
* to pass in any parameters, this is the first Void in the template
*/
@Override
protected Void doInBackground(Void... params) {
// other stuff you need to do in the background. Since you want an
// all-or-nothing type thing, we will use a transaction to manually
// control the db
db.beginTransaction();
try {
// do network I/O to retrieve what you need and then write to DB.
...
... // if theres a loop in here somewhere when reading the data, check !isCancelled() as part of the condition or as one of the first statements and then break
...
db.setTransactionSuccessful(); // assuming everything works, need to set
// this successful here at the end of the try
} catch (InterruptedException ie) { // or some other exception
cancel(true); // heres where you can call cancel() if youve been interrupted
} catch (IOException ioe) { // if your network connection has problems
cancel(true);
} finally {
db.endTransaction();
// other cleanup, like closing the HTTP connection...
// no need to close the DB if you implement it properly
}
return null; // if there was some return value, that would go here
}
@Override
protected void onCancelled(Void result) {
// depending on how you implement doInBackground(), you may not even need this,
// unless you have a lot of other "state" you need to reset aside from the DB transaction
}
@Override
protected void onPostExecute(Void result) {
// any other items to do on main (UI) thread after doInBackground() finishes
// remember, this only gets called if cancel() is not called!
}
}
希望有帮助 我认为在onpostexecute中,您可以处理任何您想处理的事情
private class ParseDownload extends AsyncTask<Summary, Void, Boolean> {
@Override
protected Boolean doInBackground(Summary... urls) {
for (Summary url : urls) {
url.dosomething();
if (isCanceled();) { return false;}
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
// delete * from yourtable here...
// and mark the download incomplete etc.
}
}
}
祝你好运我认为在onpostexecute中,你可以处理任何你想处理的事情
private class ParseDownload extends AsyncTask<Summary, Void, Boolean> {
@Override
protected Boolean doInBackground(Summary... urls) {
for (Summary url : urls) {
url.dosomething();
if (isCanceled();) { return false;}
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
// delete * from yourtable here...
// and mark the download incomplete etc.
}
}
}
祝你好运我知道这并不完全是你所要求的,但我不得不说,你使用异步任务做的都是错的
在许多情况下,异步任务将在您无法执行任何操作的情况下终止。对于像这样的关键任务,请使用服务
使用服务,您可以在系统重新启动服务之前停止,以防服务过早终止。然后,您可以继续您开始的内容,或者重新开始删除所有以前的下载…等等
对于异步任务,如果系统决定提前终止异步任务,则不会通知您,也不会重新启动异步任务。它只是在完全的沉默中死去。我知道这并不完全是您所要求的,但我必须说,您使用AsyncTask做的都是错误的
在许多情况下,异步任务将在您无法执行任何操作的情况下终止。对于像这样的关键任务,请使用服务
使用服务,您可以在系统重新启动服务之前停止,以防服务过早终止。然后,您可以继续您开始的内容,或者重新开始删除所有以前的下载…等等
对于异步任务,如果系统决定提前终止异步任务,则不会通知您,也不会重新启动异步任务。它只是在完全沉默中死去。谢谢你的回答!你有没有办法给我看一些关于如何做的示例代码?有点困惑谢谢你的回答!你有没有办法给我看一些关于如何做的示例代码?这有点令人困惑