123 votes

Android - Définir un délai d'attente pour une AsyncTask ?

J'ai un AsyncTask que j'exécute et qui télécharge une grande liste de données à partir d'un site web.

Dans le cas où l'utilisateur final dispose d'une connexion de données très lente ou irrégulière au moment de l'utilisation, j'aimerais faire en sorte que l'utilisateur final ait la possibilité d'accéder aux données. AsyncTask le délai d'attente après un certain temps. Ma première approche est la suivante :

MyDownloader downloader = new MyDownloader();
downloader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
  @Override
  public void run() {
      if ( downloader.getStatus() == AsyncTask.Status.RUNNING )
          downloader.cancel(true);
  }
}, 30000 );

Après le démarrage de l AsyncTask un nouveau gestionnaire est lancé qui annulera l'action de la AsyncTask après 30 secondes s'il est toujours en marche.

Est-ce une bonne approche ? Ou y a-t-il quelque chose d'intégré dans AsyncTask qui est mieux adapté à cet objectif ?

43voto

yorkw Points 24676

Oui, il y a AsyncTask.get()

myDownloader.get(30000, TimeUnit.MILLISECONDS);

Notez qu'en l'appelant dans le thread principal (AKA. UI thread), l'exécution sera bloquée, vous devrez probablement l'appeler dans un thread séparé.

18voto

Dans le cas où votre téléchargeur est basé sur une connexion URL, vous disposez d'un certain nombre de paramètres qui pourraient vous aider à définir un délai d'attente sans code complexe :

  HttpURLConnection urlc = (HttpURLConnection) url.openConnection();

  urlc.setConnectTimeout(15000);

  urlc.setReadTimeout(15000);

Si vous introduisez simplement ce code dans votre tâche asynchrone, c'est correct.

Le "Read Timeout" permet de tester un mauvais réseau tout au long du transfert.

L'option "Connection Timeout" n'est appelée qu'au début pour vérifier si le serveur est opérationnel ou non.

2voto

aleph_null Points 3636

Je ne pense pas qu'il y ait quelque chose comme ça dans AsyncTask. Votre approche semble être la bonne. Assurez-vous simplement de vérifier périodiquement la valeur de isCancelled() dans la méthode doInBackground de votre AsyncTask pour terminer cette méthode une fois que le thread de l'interface utilisateur l'annule.

Si vous voulez éviter d'utiliser le gestionnaire pour une raison quelconque, vous pourriez vérifier System.currentTimeMillis périodiquement dans votre AsyncTask et sortir au bout du compte, bien que je préfère votre solution puisqu'elle peut réellement interrompre le thread.

0voto

Mrityunjaya Points 21
         Context mContext;

         @Override
         protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
                                    mContext = this;

            //async task
            final RunTask tsk = new RunTask (); 
            tsk.execute();

            //setting timeout thread for async task
            Thread thread1 = new Thread(){
            public void run(){
                try {
                    tsk.get(30000, TimeUnit.MILLISECONDS);  //set time in milisecond(in this timeout is 30 seconds

                } catch (Exception e) {
                    tsk.cancel(true);                           
                    ((Activity) mContext).runOnUiThread(new Runnable()
                    {
                         @SuppressLint("ShowToast")
                        public void run()
                         {
                            Toast.makeText(mContext, "Time Out.", Toast.LENGTH_LONG).show();
                            finish(); //will close the current activity comment if you don't want to close current activity.                                
                         }
                    });
                }
            }
        };
        thread1.start();

         }

0voto

Vinnig Points 4

Vous pouvez mettre une condition supplémentaire pour rendre l'annulation plus robuste, par exemple,

 if (downloader.getStatus() == AsyncTask.Status.RUNNING || downloader.getStatus() == AsyncTask.Status.PENDING)
     downloader.cancel(true);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X