Подтвердить что ты не робот

Как проверить, запущена ли задача Async

У меня есть приложение, которое должно выполнить интенсивную операцию базы данных при запуске. Приложение хранит локальную копию контактов на телефоне и синхронизируется с базой данных контактов Android при запуске.

Если пользователь запускает приложение, запускается задача Async, которая синхронизирует базу данных в фоновом режиме. Если пользователь закрывает приложение, операция продолжает работать, и это нормально. Однако, если пользователь снова открывает приложение, запускается задача Async и появляется ошибка.

Есть ли способ проверить, запущена ли задача из другого экземпляра приложения?

4b9b3361

Ответ 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) 
    {
        // ...
    }

}