2013-05-02 4 views
-3

По какой-то причине мой вызов AsyncTask.cancel работает только один раз, то есть для первого экземпляра задачи, и никогда больше. Первая задача отменяется красиво и ударяет по методу onCancelled. Все остальные, похоже, игнорируют звонок cancel() и заканчивают его onPostExecute.AsyncTask.cancel работает только один раз

Задача выполнена из службы:

public class ZitFtpService extends Service implements ZitFtpServiceInterface 
{ 
//Blah blah 

public void connect(String server, int port) 
{ 
    if(!isConnecting){ 
     isConnecting = true; 
     ConnectTask task = new ConnectTask(); 
     task.execute(server, String.valueOf(port)); 
    } 
    } 
    //Blah blah blah 

Как вы можете видеть, что это новый экземпляр каждый раз. Я не понимаю, почему первый из них будет отличаться от последующих. AsyncTask частный внутренний класс:

private class ConnectTask extends AsyncTask<String, String, Boolean> { 

    @Override 
    protected Boolean doInBackground(String... params) { 

     boolean result = false; 

     try { 
      publishProgress(
        "start", "Connecting to "+ params[0] + ":" + params[1]); 
      Log.v("ZIT", params[0] + " " + params[1] + " " + params.length); 
      conn.connect(params[0], Integer.valueOf(params[1]), 1000); 
      result = true; 
      } catch (NumberFormatException e) { 
      Log.e("ZIT", e.getMessage()); 
     } catch (IOException e) { 
       failMessage = e.getMessage(); 
       e.printStackTrace(); 
      } 
     return Boolean.valueOf(result); 
    } 

    private void cancelConnect() { 
     try { 
      conn.disconnect(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      conn = new ZMobileFTPImpl(); 
     } 

     if(!(dialog==null)) { 
      dialog.dismiss(); 
     } 
    } 

    @Override 
    protected void onCancelled() { 
     Log.v("ZIT", "I was cancelled."); 
     isConnecting = false; 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 

     if(dialog == null) { 
      dialog = new ProgressDialog(progressActivity); 
      dialog.setCancelable(true); 
      dialog.setOnCancelListener(new OnCancelListener() { 

       @Override 
       public void onCancel(DialogInterface dialog) { 
        ConnectTask.this.cancel(true); 
        cancelConnect(); 
        dialog.dismiss(); 

       } 
      }); 
      dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
        new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 
     } 

     dialog.setMessage(values[1]); 
     dialog.setCancelable(true); 
     dialog.show(); 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 

     dialog.dismiss(); 
     if(!result) { 
      AlertDialog.Builder builder = 
        new AlertDialog.Builder(progressActivity); 
      builder.setMessage(failMessage).setTitle("Error"); 
      failMessage = ""; 
      builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int id) { 
         dialog.dismiss(); 
        } 
       }); 
      AlertDialog failDialog = builder.create(); 
      failDialog.show(); 
     } 

     isConnecting = false; 
    } 
} 
+0

Трудно сказать, но больше всего это какая-то ошибка в коде. Вы используете глобальные переменные в вашей AsyncTask, также вы используете эти переменные, чтобы определить, запускать ли новую задачу или нет. Отлаживайте процесс создания своей задачи – httpdispatch

ответ

1

From Doc's

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

класс
  • AsyncTask должен быть загруженный в поток пользовательского интерфейса. Это делается автоматически с JELLY_BEAN.
  • Экземпляр задачи должен быть создан в потоке пользовательского интерфейса.
  • execute(Params...) должно быть вызвано в потоке пользовательского интерфейса.
  • Не звоните onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) вручную.
  • задача может быть выполнена только один раз (исключение будет сгенерировано, если второе исполнение попытки.)

Таким образом, вы можете вызывать AsyncTask несколько раз, создавая новый экземпляр каждый раз, как

new ConnectTask().execute(params); 
0

Это намеренное, как вы можете только выполнить экземпляр AsyncTask один раз, вы можете запустить task.execute несколько раз, хотя ...

во всяком случае, я полагаю, вы забыли добавить super.onCancelled в следующем переопределении:

@Override 
public void onCancelled() { 
    //... 
    super.onCancelled(); 
} 

Попробуйте, если это помогло, и в противном случае вы должны разделить ошибку или войти, чтобы мы могли устранить, что :)

Смежные вопросы