Android Uso di base

Esempio

In Attività e servizi Android, la maggior parte dei callback vengono eseguiti sul thread principale . Ciò semplifica l'aggiornamento dell'interfaccia utente, ma l'esecuzione di attività gravose di processore o I / O sul thread principale può causare la sospensione dell'interfaccia utente e la mancata risposta ( documentazione ufficiale su ciò che accade).

Puoi rimediare mettendo queste attività più pesanti su un thread in background.

Un modo per farlo è usare AsyncTask , che fornisce un framework per facilitare l'uso di un thread in background e anche eseguire attività Thread UI prima, durante e dopo lo sfondo Thread ha completato il suo lavoro.

Metodi che possono essere sovrascritti durante l'estensione di AsyncTask :

  • onPreExecute() : richiamato sul thread UI prima onPreExecute()
  • doInBackground() : richiamato sul thread in background immediatamente dopo che onPreExecute() termina l'esecuzione.
  • onProgressUpdate() : richiamato sul thread dell'interfaccia utente dopo una chiamata a publishProgress(Progress...) .
  • onPostExecute() : richiamato sul thread dell'interfaccia utente al termine del calcolo dello sfondo

Esempio

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.");
        }
    }

}

Uso:

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

o semplicemente:

new MyCustomAsyncTask().execute(userSuppliedFilename);

Nota

Quando AsyncTask un AsyncTask possiamo passare tre tipi tra parentesi < > .
Definito come <Params, Progress, Result> (vedere la sezione Parametri )

Nell'esempio precedente abbiamo utilizzato i tipi <File, Void, String> :

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

Void viene utilizzato quando si desidera contrassegnare un tipo come non usato.

Si noti che non è possibile passare i tipi primitivi (cioè int , float e altri 6) come parametri. In questi casi, dovresti passare le loro classi wrapper , ad esempio Integer anziché int , o Float invece di float .

Il ciclo di vita AsyncTask e Activity

AsyncTasks non segue il ciclo di vita delle istanze di attività. Se si avvia un AsyncTask all'interno di un'attività e si ruota il dispositivo, l'attività verrà distrutta e verrà creata una nuova istanza. Ma AsyncTask non morirà. Continuerà a vivere fino al suo completamento.

Soluzione: AsyncTaskLoader

Una sottoclasse di Caricatori è AsyncTaskLoader. Questa classe svolge la stessa funzione dell'AsyncTask, ma molto meglio. Può gestire le modifiche alla configurazione delle attività più facilmente e si comporta nei cicli di vita di Fragments and Activities. La cosa bella è che AsyncTaskLoader può essere utilizzato in qualsiasi situazione in cui viene utilizzato AsyncTask. Ogni volta che i dati devono essere caricati in memoria per l'attività / frammento da gestire, AsyncTaskLoader può fare meglio il lavoro.