2013-05-02 5 views
-3

Pour une raison quelconque, mon appel à AsyncTask.cancel ne fonctionne qu'une seule fois, c'est-à-dire pour la première instance de la tâche, et jamais plus. La première tâche s'annule magnifiquement et frappe la méthode onCancelled. Tous les autres semblent ignorer l'appel cancel() et finissent dans onPostExecute.AsyncTask.cancel ne fonctionne qu'une seule fois

La tâche est exécutée à partir d'un service:

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 

Comme vous pouvez le voir, il est une nouvelle instance à chaque fois. Je ne vois pas pourquoi le premier se comporterait différemment des suivants. Le AsyncTask est une classe privée intérieure:

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

Difficile à dire, mais la plupart de tout ce qu'il ya une erreur dans votre code. Vous utilisez des variables globales dans votre AsyncTask, vous utilisez également ces variables pour déterminer si vous souhaitez exécuter une nouvelle tâche ou non. Veuillez déboguer à travers le processus de création de votre tâche – httpdispatch

Répondre

1

From Doc's

Il y a quelques règles de filetage qui doivent être suivies pour cette classe fonctionne correctement:

  • La classe AsyncTask doit être chargé sur le thread UI. Ceci est fait automatiquement à partir de JELLY_BEAN.
  • L'instance de tâche doit être créée sur le thread d'interface utilisateur.
  • execute(Params...) doit être appelée sur le thread d'interface utilisateur. Ne pas appeler onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manuellement.
  • La tâche peut être exécutée qu'une seule fois (une exception sera levée si une seconde exécution est tentée.)

Ainsi, vous pouvez appeler un plusieurs fois AsyncTask en créant nouvelle instance à chaque fois comme

new ConnectTask().execute(params); 
0

Ceci est intentionnel que vous ne pouvez exécuter une instance de AsyncTask une fois, vous pouvez exécuter task.execute plusieurs fois mais ...

Quoi qu'il en soit, je crois que vous avez oublié d'ajouter le super.onCancelled en remplacement suivant:

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

Essayez si cela a aidé, et sinon vous devez partager l'erreur ou ouvrir une session afin que nous puissions résoudre les problèmes que :)

Questions connexes