我正在使用AsyncTask来填充SQLite数据库。我正在从某个网页下载数据并将其放入SQLite表中。问题是,我想下载100%的数据或者没有。因此,如果AsyncTask由于某种原因被中断,我想删除目前已下载的所有数据。
这就是我尝试这样做的方式:
@Override
protected void onCancelled() {
super.onCancelled();
dbHandler.deleteFromDatabase(razred);
Log.i("TAG", "AsyncTask cancelled");
}
我认为如果AsyncTask以任何方式中断但是它没有中断,那么“onCancelled”将会执行。如果以任何方式取消AsyncTask,我该如何删除使用AsyncTask创建的数据? (例如,活动暂停,活动被破坏,互联网连接中断等)。
答案 0 :(得分:3)
您走在正确的轨道上,但在doInBackground()
中,您还需要专门致电isCancelled()
以检查它是否已取消,然后从doInBackground()
返回。然后您的代码将正常工作。
请参阅AsyncTask
documentation了解“取消任务”
以下是文档中的引用,以便于参考:
可以随时通过调用
cancel(boolean)
取消任务。调用此方法将导致后续调用isCancelled()
返回true。调用此方法后,onCancelled(Object)
将在onPostExecute(Object)
返回后调用,而不是doInBackground(Object[])
。为了确保尽快取消任务,您应该始终从isCancelled()
定期检查doInBackground(Object[])
的返回值,如果可能的话(例如在循环内)。
编辑:每个请求,一些示例代码:
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!
}
}
希望有所帮助!
答案 1 :(得分:1)
我知道这不是你要求的,但我不得不说你使用AsyncTask做错了。
在很多情况下,您的异步任务将终止,而您无法执行任何操作。对于此类关键任务,请使用服务。
使用服务,您可以直到系统重新启动服务,以防它过早终止。然后,您可以继续开始,或重新开始(删除所有以前的下载等)。
使用AsyncTask ,如果系统决定提前终止您的异步任务,则不会通知您,也不会重新启动AsyncTask。它完全沉默了。
答案 2 :(得分:0)
我认为在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.
}
}
}
祝你好运