asynctask внутри runnable не останавливается после вызова removeCallbacks

У меня есть асинхронная задача с именем myAsync, которая выполняет некоторые сетевые операции (извлечение данных с сервера и анализ json).

У меня также есть обработчик, созданный после запуска действия.

У меня также есть runnable, в котором я запускаю асинтаск. Причина, по которой я использую runnable, заключается в том, что я буду использовать его внутри метода postdelayed обработчика, поскольку я хочу, чтобы это повторялось каждую минуту.

Runnable runnable = new Runnable()
{
    public void run()
    {
        new myAsync ().execute();
    }
};

Затем я использую вышеуказанный исполняемый файл внутри моего onResume;

@Override
protected void onResume()
{
    super.onResume();
            handler.postDelayed(runnable, 60000);
    }

Всякий раз, когда я ухожу с мероприятия, я хочу, чтобы проверка остановилась, поэтому я звоню,

 handler.removeCallbacks(runnable);

Однако асинтаск продолжает работать без остановок. Что мне делать ?


person tony9099    schedule 24.09.2013    source источник
comment
Вы можете установить его на null?   -  person Si8    schedule 24.09.2013
comment
когда вы говорите, что он продолжает работать, вы имеете в виду, что AsyncTask не останавливает свой текущий процесс или запускается каждую минуту?   -  person tyczj    schedule 24.09.2013
comment
что ?????? (много вопросов, чтобы комментарий был опубликован: P)   -  person tony9099    schedule 24.09.2013
comment
@tyczj асинхронная задача не останавливает свой текущий процесс, а также повторяется на второй минуте.   -  person tony9099    schedule 24.09.2013


Ответы (3)


Весь смысл asynctask состоит в том, чтобы запустить поток в основном потоке. Так что нет смысла запускать его в Runnable()

person meda    schedule 24.09.2013
comment
но я хочу, чтобы он повторялся каждые x раз, поэтому я использую метод postdelayed обработчика, который принимает runnables, поэтому я помещаю его внутрь runnable. какая альтернатива? - person tony9099; 24.09.2013

Что вы можете сделать, так это пропустить Runnable и Handler... здесь они определенно не нужны. Предполагая, что AsyncTask является внутренним классом вашего Activity, вы можете установить логическую переменную члена и проверить это в своем doInBackground()

public Void doInBackground(Void...params)
{
     // this is a boolean variable, declared as an
     //Activity member variable, that you set to true when starting the task
     while (flag)  
     {
         // run your code
         Thread.sleep(60000);
     }

     return null; // here you can return control to onPostExecute()
                  // if you need to do anything there
}

Это заставит AsyncTask заснуть на минуту, прежде чем снова запустить код. Затем в onPause() или где угодно вы устанавливаете флаг в false. Если вам нужно обновить UI, позвоните publishProgress() внутри вашего loop и введите код UI в onProgressUpdate().

person codeMagic    schedule 24.09.2013
comment
хороший подход, однако не думал об этом таким образом, когда в этом случае вызывается onPostExecute? Я предполагаю, что никогда. Кстати, это надежный подход? т.е. люди используют этот обходной путь? - person tony9099; 24.09.2013
comment
Я немного отредактировал код. Вы можете это сделать после окончания loop, если вам нужно что-то сделать в onPostExecute(). - person codeMagic; 24.09.2013
comment
идеально. Можете ли вы придумать другие варианты решения проблемы? - person tony9099; 24.09.2013
comment
Я, наверное, мог бы, если бы очень хорошо подумал, но я не понимаю, что вас беспокоит по этому поводу... Я не могу придумать ничего более простого и легко реализуемого. - person codeMagic; 24.09.2013
comment
верно. Я попробую и дам вам знать. - person tony9099; 24.09.2013
comment
давайте продолжим это обсуждение в чате - person tony9099; 24.09.2013
comment
+1 хорошо, может потому что бесконечный цикл? как вы думаете, это может случиться - person meda; 24.09.2013
comment
@meda Спасибо. Нет, это не будет бесконечно, потому что вы меняете flag на false в onPause(), что прерывает цикл каждый раз, когда Activity уничтожается или что-то происходит перед ним. - person codeMagic; 24.09.2013

Вы можете удалить AsyncTask и просто выполнить процесс с помощью Runnable, таким образом, вы можете делать нужные вам повторения. Если это не сработает, вы можете установить флаг, чтобы остановить процесс, как указано в codeMagic.

runable = new Runnable() {  
 public void run() {
  try {
   //Proccess
   while (flag)  
   {
    //Proccess
    handler.postDelayed(this, 3000);
   }
  }catch(Exception e)
  {
   Log.i("Log","Error: "+e);                                        
  }
 };
handler.postDelayed(runable, 3000);



@Override
 public void onPause() {
    super.onPause();
   flag=false;
   handler.removeCallbacks(runnable);
 }

 @Override
 public void onResume() {
    super.onResume();
   flag=true;
   handler.postDelayed(runable, 3000);
 }

Я надеюсь, что это поможет.

person Mtn    schedule 24.09.2013
comment
Могу ли я делать сетевые вещи внутри public void run(), потому что, насколько я понимаю, я запускаю этот runnable в пользовательском интерфейсе и не могу делать там сетевые вещи. - person tony9099; 25.09.2013
comment
Проверьте это: stackoverflow.com/questions/6531950/ - person Mtn; 25.09.2013