Android Utilisation de base


Exemple

Dans Activités et services Android, la plupart des rappels sont exécutés sur le thread principal . Cela simplifie la mise à jour de l'interface utilisateur, mais l'exécution de tâches lourdes sur le processeur ou l'E / S sur le thread principal peut entraîner une pause de votre interface utilisateur et une absence de réponse ( documentation officielle sur ce qui se passe alors).

Vous pouvez remédier à cela en plaçant ces tâches plus lourdes sur un thread d'arrière-plan.

Pour ce faire, vous pouvez utiliser une AsyncTask , qui fournit un cadre facilitant l'utilisation d'un thread en arrière-plan, et effectue également des tâches UI Thread avant, pendant et après la fin du thread Thread.

Méthodes pouvant être remplacées lors de l'extension d' AsyncTask :

  • onPreExecute() : invoqué sur le thread d'interface utilisateur avant l' exécution de la tâche
  • doInBackground() : invoqué sur le thread d'arrière-plan immédiatement après l' onPreExecute() de onPreExecute() .
  • onProgressUpdate() : invoqué sur le thread d'interface utilisateur après un appel à publishProgress(Progress...) .
  • onPostExecute() : invoqué sur le thread d'interface utilisateur une fois le calcul en arrière-plan terminé

Exemple

public class MyCustomAsyncTask extends AsyncTask<File, Void, String> {

    
    @Override
    protected void onPreExecute(){
        // This runs on the UI thread before the background thread executes.
        super.onPreExecute();
        // Do pre-thread tasks such as initializing variables. 
        Log.v("myBackgroundTask", "Starting Background Task");  
    }

    @Override
    protected String doInBackground(File... params) {
        // Disk-intensive work. This runs on a background thread.
        // Search through a file for the first line that contains "Hello", and return
        // that line.
        try (Scanner scanner = new Scanner(params[0])) {
            while (scanner.hasNextLine()) {
                final String line = scanner.nextLine();
                publishProgress(); // tell the UI thread we made progress

                if (line.contains("Hello")) {
                    return line;
                }
            }
            return null;
        }
    }

    @Override
    protected void onProgressUpdate(Void...p) {
        // Runs on the UI thread after publishProgress is invoked
        Log.v("Read another line!")
    }        

    @Override
    protected void onPostExecute(String s) {
        // This runs on the UI thread after complete execution of the doInBackground() method
        // This function receives result(String s) returned from the doInBackground() method.
        // Update UI with the found string.
        TextView view = (TextView) findViewById(R.id.found_string);
        if (s != null) {
            view.setText(s);
        } else {
            view.setText("Match not found.");
        }
    }

}

Usage:

MyCustomAsyncTask asyncTask = new MyCustomAsyncTask<File, Void, String>();
// Run the task with a user supplied filename.
asyncTask.execute(userSuppliedFilename);

ou simplement:

new MyCustomAsyncTask().execute(userSuppliedFilename);

Remarque

Lors de la définition d'une AsyncTask nous pouvons passer trois types entre < > .
Défini comme <Params, Progress, Result> (voir la section Paramètres )

Dans l'exemple précédent, nous avons utilisé les types <File, Void, String> :

AsyncTask<File, Void, String>
// Params has type File
// Progress has unused type
// Result has type String

Void est utilisé lorsque vous souhaitez marquer un type comme non utilisé.

Notez que vous ne pouvez pas passer de types primitifs (c.-à-d. int , float et 6 autres) en tant que paramètres. Dans de tels cas, vous devez passer leurs classes wrapper , par exemple Integer au lieu de int , ou Float au lieu de float .

Le cycle de vie AsyncTask et Activity

AsyncTasks ne suit pas le cycle de vie des instances d'activité. Si vous démarrez une tâche AsyncTask dans une activité et que vous faites pivoter le périphérique, l'activité sera détruite et une nouvelle instance sera créée. Mais la AsyncTask ne mourra pas. Il continuera à vivre jusqu'à la fin.

Solution: AsyncTaskLoader

Une sous-classe de chargeurs est AsyncTaskLoader. Cette classe remplit la même fonction que AsyncTask, mais beaucoup mieux. Il peut gérer plus facilement les modifications de la configuration d'activité et se comporte au cours des cycles de vie des fragments et des activités. La bonne chose est que AsyncTaskLoader peut être utilisé dans toutes les situations où AsyncTask est utilisé. Chaque fois que des données doivent être chargées en mémoire pour que l'activité / le fragment puisse être géré, AsyncTaskLoader peut mieux faire le travail.