Как проверить, запущена ли задача Async
У меня есть приложение, которое должно выполнить интенсивную операцию базы данных при запуске. Приложение хранит локальную копию контактов на телефоне и синхронизируется с базой данных контактов Android при запуске.
Если пользователь запускает приложение, запускается задача Async, которая синхронизирует базу данных в фоновом режиме. Если пользователь закрывает приложение, операция продолжает работать, и это нормально. Однако, если пользователь снова открывает приложение, запускается задача Async и появляется ошибка.
Есть ли способ проверить, запущена ли задача из другого экземпляра приложения?
Ответы
Ответ 1
Я думаю, вы должны проверить концепцию Application
в 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
Удачи!
Ответ 2
Используйте getStatus()
, чтобы получить статус вашего AsyncTask
. Если статус AsyncTask.Status.RUNNING
, ваша задача выполняется.
РЕДАКТИРОВАТЬ: вам следует пересмотреть свою реализацию и удерживать AsyncTask
, возможно, в Service
или IntentService
, чтобы извлечь ваши данные из Интернета.
Ответ 3
Да. Ребята, это некоторые из примеров.
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
}
Ответ 4
Мне удалось справиться с этой проблемой с помощью своего рода шаблона 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)
{
// ...
}
}