我有一个应用程序需要在启动时执行密集的数据库操作。该应用程序在手机上保存联系人的本地副本,并在启动时与Android联系人数据库同步。
如果用户启动应用程序,则启动异步任务,在后台执行数据库同步。如果用户关闭应用程序,操作将继续运行,这很好。但是,如果用户再次打开应用程序,则会启动异步任务并生成错误。
有没有检查任务是否已经从应用程序的其他实例运行?
答案 0 :(得分:91)
使用getStatus()
获取AsyncTask
的状态。如果状态为AsyncTask.Status.RUNNING
,那么您的任务正在运行。
编辑:您应该重新考虑您的实施,并将AsyncTask
放在Service
或IntentService
,以便从网上获取您的数据。
答案 1 :(得分:33)
是的,伙计这些是一些例子。
LoadMusicInBackground lmib = new LoadMusicInBackground();
if(lmib.getStatus() == AsyncTask.Status.PENDING){
// My AsyncTask has not started yet
}
if(lmib.getStatus() == AsyncTask.Status.RUNNING){
// My AsyncTask is currently doing work in doInBackground()
}
if(lmib.getStatus() == AsyncTask.Status.FINISHED){
// My AsyncTask is done and onPostExecute was called
}
答案 2 :(得分:6)
我设法用某种Singleton模式处理这个问题。 希望它有所帮助。
// fill the places database from a JSON object
public class myAsyncTask extends AsyncTask<Void,Integer,Integer> {
Activity mContext = null;
static AsyncTask<Void,Integer,Integer> myAsyncTaskInstance = null;
// Private Constructor: can't be called from outside this class
private myAsyncTask(Activity iContext) {
mContext = iContext;
}
public static AsyncTask<Void, Integer, Integer> getInstance(Activity iContext) {
// if the current async task is already running, return null: no new async task
// shall be created if an instance is already running
if (myAsyncTaskInstance != null && myAsyncTaskInstance.getStatus() == Status.RUNNING) {
// it can be running but cancelled, in that case, return a new instance
if (myAsyncTaskInstance.isCancelled()) {
myAsyncTaskInstance = new myAsyncTask(iContext);
} else {
// display a toast to say "try later"
Toast.makeText(iContext, "A task is already running, try later", Toast.LENGTH_SHORT).show();
return null;
}
}
//if the current async task is pending, it can be executed return this instance
if (myAsyncTaskInstance != null && myAsyncTaskInstance.getStatus() == Status.PENDING) {
return myAsyncTaskInstance;
}
//if the current async task is finished, it can't be executed another time, so return a new instance
if (myAsyncTaskInstance != null && myAsyncTaskInstance.getStatus() == Status.FINISHED) {
myAsyncTaskInstance = new myAsyncTask(iContext);
}
// if the current async task is null, create a new instance
if (myAsyncTaskInstance == null) {
myAsyncTaskInstance = new myAsyncTask(iContext);
}
// return the current instance
return myAsyncTaskInstance;
}
@Override
protected Integer doInBackground(Void... iUnUsed) {
// ...
}
}
答案 3 :(得分:3)
我认为您应该检查Application
中Android
的概念。
http://developer.android.com/reference/android/app/Application.html
实际上没有
这样的东西应用的不同实例
。所有Application
的{{1}}始终相同
这意味着您已离开Activities/Services.
并再次打开它,有两种情况可能:
Activity
已经死了,开始一个新的AsyncTask
仍然存在,因此Application
可能仍在运行。在第二种情况下,我建议使用一些静态变量,指向此AsyncTask
或它的状态。如果您的应用程序在第二次打开时仍处于活动状态 - 所有静态引用仍然有效,因此您可以成功运行。
PS:顺便说一句,在当前的方法中,请注意您的应用程序可以随时被系统终止。所以AsyncTask
可以随时中断。它对你不好 - 请检查AsyncTask
- 专为背景操作目的而设计的组件。 http://developer.android.com/reference/android/app/IntentService.html