Android 如何检查异步任务是否已在运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12236899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if Async Task is already running
提问by Kevin Bradshaw
I have an app that needs to do an intensive database operation on start up. The app holds a local copy of the contacts on the phone and synchronizes with the android contact database on startup.
我有一个应用程序需要在启动时执行密集的数据库操作。该应用程序在手机上保存联系人的本地副本,并在启动时与 android 联系人数据库同步。
If a user starts the app, an Async Task is started that does the database synch in the background. If the user closes the app, the operation continues running which is fine. However if the user opens the app again, the Async Task is started and an error is produced.
如果用户启动应用程序,则会启动一个异步任务,在后台进行数据库同步。如果用户关闭应用程序,操作会继续运行,这很好。但是,如果用户再次打开该应用程序,则会启动异步任务并产生错误。
Is there anyway of checking if the Task is already running from a different instance of the app?
有没有检查任务是否已经从应用程序的不同实例运行?
采纳答案by AlexN
I think you should check the concept of Application
in Android
.
http://developer.android.com/reference/android/app/Application.html
我认为你应该检查Application
in的概念Android
。
http://developer.android.com/reference/android/app/Application.html
In fact there is no such thing as
事实上,没有这样的事情
different instance of the app
应用程序的不同实例
. The Application
is always the same for all your Activities/Services.
That means that you'd left the Activity
and opened it again, 2 cases are possible:
. 该Application
始终都是一样的你的Activities/Services.
那意味着你已经离开了Activity
,并再次打开它,其中2例是可能的:
- The system already killed your application. In this case
AsyncTask
is dead already and it's safe to start a new one - The
Application
was still alive, soAsyncTask
possibly still running.
- 系统已经终止了您的应用程序。在这种情况下
AsyncTask
已经死了,可以安全地开始一个新的 - 在
Application
还活着,所以AsyncTask
可能仍在运行。
In 2nd case I will recommend to use some static variables, pointing to this AsyncTask
or it's state. If your app was still alive when 2nd time opened - all static references will be still valid, so you can successfully operate.
在第二种情况下,我会建议使用一些静态变量,指向 thisAsyncTask
或它的状态。如果您的应用程序在第二次打开时仍然处于活动状态 - 所有静态引用仍然有效,因此您可以成功运行。
PS: By the way, in current approach be aware that your application can be terminated by the system at any time. So AsyncTask
can be interrupted in any moment. It it's not ok for you - please check IntentServices
- components, specially designed for background-operation purpose. http://developer.android.com/reference/android/app/IntentService.html
PS:顺便说一句,在当前的方法中,请注意您的应用程序可以随时被系统终止。所以AsyncTask
随时都可以被打断。这对您来说不合适 - 请检查IntentServices
- 专门为后台操作目的而设计的组件。http://developer.android.com/reference/android/app/IntentService.html
Good luck!
祝你好运!
回答by Ovidiu Latcu
Use getStatus()
to get the status of your AsyncTask
. If status is AsyncTask.Status.RUNNING
then your task is running.
使用getStatus()
让您的状态AsyncTask
。如果 status 是AsyncTask.Status.RUNNING
那么您的任务正在运行。
EDIT:you should reconsider your implementation and hold the AsyncTask
probably in a Service
or IntentService
to fetch your data from the web.
编辑:您应该重新考虑您的实现并将AsyncTask
可能保存在 aService
或 中IntentService
以从网络获取您的数据。
回答by Ahmad Arslan
Yes Right guys these are some of the examples.
是的,这些都是一些例子。
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
}
回答by Jeremy Heitz
I've managed to handle this problem with some sort of Singleton pattern. Hope it helps.
我已经设法用某种单例模式来处理这个问题。希望能帮助到你。
// 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) {
// ...
}
}