我有一个应用程序需要在启动时进行密集的数据库操作。该应用程序保存手机上联系人的本地副本,并在启动时与 android 联系人数据库同步。
如果用户启动应用程序,则会启动一个在后台执行数据库同步的异步任务。如果用户关闭应用程序,操作会继续运行,这很好。但是,如果用户再次打开应用程序,则会启动异步任务并产生错误。
无论如何检查任务是否已经从应用程序的不同实例运行?
我有一个应用程序需要在启动时进行密集的数据库操作。该应用程序保存手机上联系人的本地副本,并在启动时与 android 联系人数据库同步。
如果用户启动应用程序,则会启动一个在后台执行数据库同步的异步任务。如果用户关闭应用程序,操作会继续运行,这很好。但是,如果用户再次打开应用程序,则会启动异步任务并产生错误。
无论如何检查任务是否已经从应用程序的不同实例运行?
用于getStatus()
获取您的AsyncTask
. 如果状态为,AsyncTask.Status.RUNNING
则您的任务正在运行。
编辑:您应该重新考虑您的实施并将AsyncTask
可能的保留在Service
或IntentService
从网络上获取您的数据。
是的,伙计们,这些是一些例子。
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
}
我已经设法用某种单例模式处理了这个问题。希望能帮助到你。
// 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) {
// ...
}
}
我认为您应该检查Application
in的概念Android
。
http://developer.android.com/reference/android/app/Application.html
事实上,没有这样的事情
应用程序的不同实例
. 对你所有的Application
人来说总是一样的Activities/Services.
这意味着你已经离开Activity
并再次打开它,2种情况是可能的:
AsyncTask
已经死了,可以安全地开始一个新的Application
还活着,所以可能AsyncTask
还在运行。在第二种情况下,我建议使用一些静态变量,指向这个AsyncTask
或它的状态。如果您的应用在第二次打开时仍然存在 - 所有静态引用仍然有效,因此您可以成功操作。
PS:顺便说一下,在当前方法中,请注意您的应用程序可以随时被系统终止。所以AsyncTask
可以随时被打断。它不适合您 - 请检查IntentServices
- 组件,专为后台操作目的而设计。http://developer.android.com/reference/android/app/IntentService.html
祝你好运!