Esempio di Android di AsyncTask


680

Stavo leggendo AsyncTaske ho provato il semplice programma qui sotto. Ma non sembra funzionare. Come posso farlo funzionare?

public class AsyncTaskActivity extends Activity {

    Button btn;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener((OnClickListener) this);
    }

    public void onClick(View view){
        new LongOperation().execute("");
    }

    private class LongOperation extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            for(int i=0;i<5;i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

Sto solo cercando di cambiare l'etichetta dopo 5 secondi nel processo in background.

Questo è il mio main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" >
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="10"
        android:padding="10dip">
    </ProgressBar>
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Progress" >
    </Button>
    <TextView android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace"/>
</LinearLayout>

1
inoltre è possibile mostrare lo stato di avanzamento richiamando publishingprogress () dal metodo doInBackground ().
osum,


ecco un esempio asincrono di scaricare anche l'immagine: android-ios-tutorials.com/182/…
Houcine


3
semplice esempio ... Devi leggere il link
c49,

Risposte:


702

Ok, stai provando ad accedere alla GUI tramite un altro thread. Questa, in linea di massima, non è una buona pratica.

AsyncTask esegue tutto doInBackground()all'interno di un altro thread, che non ha accesso alla GUI in cui si trovano le visualizzazioni.

preExecute()e postExecute()ti offre l'accesso alla GUI prima e dopo che si è verificato il sollevamento pesante in questo nuovo thread e puoi anche passare il risultato della lunga operazione per postExecute()mostrare quindi i risultati dell'elaborazione.

Vedi queste righe dove in seguito aggiorni TextView:

TextView txt = findViewById(R.id.output);
txt.setText("Executed");

Mettili dentro onPostExecute().

Vedrai quindi il tuo testo TextView aggiornato dopo il doInBackgroundcompletamento.

Ho notato che il tuo listener onClick non controlla per vedere quale vista è stata selezionata. Trovo che il modo più semplice per farlo sia tramite le istruzioni switch. Ho una classe completa modificata di seguito con tutti i suggerimenti per salvare la confusione.

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class AsyncTaskActivity extends Activity implements OnClickListener {

    Button btn;
    AsyncTask<?, ?, ?> runningTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = findViewById(R.id.button1);

        // Because we implement OnClickListener, we only
        // have to pass "this" (much easier)
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        // Detect the view that was "clicked"
        switch (view.getId()) {
        case R.id.button1:
            if (runningTask != null)
                runningTask.cancel(true);
            runningTask = new LongOperation();
            runningTask.execute();
            break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Cancel running task(s) to avoid memory leaks
        if (runningTask != null)
            runningTask.cancel(true);
    }

    private final class LongOperation extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // We were cancelled; stop sleeping!
                }
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed"); // txt.setText(result);
            // You might want to change "executed" for the returned string
            // passed into onPostExecute(), but that is up to you
        }
    }
}

2
Non riesco a fare questo <code> btn.setOnClickListener (questo); </code> Eclipse restituisce un errore ----- "Il metodo setOnClickListener (View.OnClickListener) nel tipo Visualizza non è applicabile per gli argomenti (AsyncTaskActivity)"
Fox

Consiglio di cambiare l'impostazione del testo in modo che non sia statica, ma prendo l'argomento dal onPostExecute(String result)metodo. Ciò renderebbe più chiaro per i futuri lettori che l'argomento è popolato dal valore di ritorno di doInBackground(String... params).
Eric,

@Eric Tobias - Esatte cose già fatte nella sezione commentata. Stavo seguendo e rispondendo alla domanda degli utenti nel mio esempio completo.
Graham Smith,

1
Come addendum e goeder seeder (e proveniente da qualcuno che attualmente sta imparando queste cose, ecco come mi sono imbattuto in questo): la maggior parte degli aggiornamenti dell'interfaccia utente che farai per qualcosa in cui hai bisogno di progressi segnalati all'utente è nella richiamata su ProgressUpdate che viene eseguito nel thread dell'interfaccia utente principale.
RichieHH

1
Questo sicuramente rovinerà se la tua attività viene ruotata o distrutta per qualsiasi motivo ...
Sam,

792

La mia risposta completa è qui , ma ecco un'immagine esplicativa per integrare le altre risposte in questa pagina. Per me, capire dove stavano andando tutte le variabili è stata la parte più confusa all'inizio.

inserisci qui la descrizione dell'immagine


3
paramsè un array. (Nell'esempio sopra, era un Stringarray.) Ciò consente di passare più parametri dello stesso tipo. Poi si può accedere a questi parametri con params[0], params[1], params[2], ecc Nel esempio, c'era solo un singolo Stringnella paramsmatrice. Se è necessario passare più parametri di tipi diversi (ad esempio, a Stringe an int), vedere questa domanda .
Suragch,

73

Sono sicuro che si sta eseguendo correttamente, ma stai cercando di cambiare gli elementi dell'interfaccia utente nel thread in background e questo non funzionerà.

Rivedi la tua chiamata e AsyncTask come segue:

Classe di chiamata

Nota: suggerisco personalmente di utilizzare onPostExecute()ovunque eseguiate il thread AsyncTask e non nella classe che estende AsyncTask stesso. Penso che faciliti la lettura del codice, soprattutto se hai bisogno di AsyncTask in più punti gestendo i risultati in modo leggermente diverso.

new LongThread() {
    @Override public void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}.execute("");

Classe LongThread (estende AsyncTask):

@Override
protected String doInBackground(String... params) {
    for (int i = 0; i < 5; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return "Executed";
}      

7
Grazie per aver fornito un esempio che separa l'AsyncTask dall'attività
sthomps

1
sì, finalmente qualcuno disaccoppia il compito e l'attività. grazie. E ignorare onPostExecutel'attività in è geniale.
MCY

58

Concetto e codice qui

Ho creato un semplice esempio per l'utilizzo di AsyncTask di Android. Inizia con onPreExecute(), doInBackground(), publishProgress()e infine onProgressUpdate().

In questo, doInBackground () funziona come thread in background, mentre altri funzionano nel thread dell'interfaccia utente. Non è possibile accedere a un elemento dell'interfaccia utente in doInBackground (). La sequenza è la stessa che ho menzionato.

Tuttavia, se è necessario aggiornare qualsiasi widget da doInBackground, è possibile publishProgressda doInBackgroundcui chiamare onProgressUpdateper aggiornare il widget dell'interfaccia utente.

class TestAsync extends AsyncTask<Void, Integer, String> {
    String TAG = getClass().getSimpleName();

    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG + " PreExceute","On pre Exceute......");
    }

    protected String doInBackground(Void...arg0) {
        Log.d(TAG + " DoINBackGround", "On doInBackground...");

        for (int i=0; i<10; i++){
            Integer in = new Integer(i);
            publishProgress(i);
        }
        return "You are at PostExecute";
    }

    protected void onProgressUpdate(Integer...a) {
        super.onProgressUpdate(a);
        Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d(TAG + " onPostExecute", "" + result);
    }
}

Chiamalo così nella tua attività:

new TestAsync().execute();

Riferimenti per gli sviluppatori qui


3
le lezioni iniziano con in genere lettere maiuscole in Java, di solito è seguita una notazione
Vamsi Pavan Mahesh

20

Sposta queste due linee:

TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");

fuori dal doInBackgroundmetodo di AsyncTask e inseriscili nel onPostExecutemetodo. Il tuo AsyncTaskdovrebbe essere simile a questa:

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(5000); // no need for a loop
        } catch (InterruptedException e) {
            Log.e("LongOperation", "Interrupted", e);
            return "Interrupted";
        }
        return "Executed";
    }      

    @Override
    protected void onPostExecute(String result) {               
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}

Ehi, cosa sto eseguendo attività asincrona sul servizio, voglio restituire un valore al thread dell'interfaccia utente principale.
Dipen,

@Dipen - Dai un'occhiata a questa discussione . Ci sono due problemi: riportare i risultati di un AsyncTask, che la mia risposta affronta; e l'invio di un valore da un servizio al thread dell'interfaccia utente, che l'altra discussione affronta. Questi problemi sono indipendenti.
Ted Hopp,

14

Sfondo / Teoria

AsyncTask ti consente di eseguire un'attività su un thread in background, mentre pubblica i risultati nel thread dell'interfaccia utente.

L'utente dovrebbe sempre essere in grado di interagire con l'app, quindi è importante evitare di bloccare il thread principale (UI) con attività come il download di contenuti dal Web.

Questo è il motivo per cui usiamo un AsyncTask.

Offre un'interfaccia semplice racchiudendo la coda e il gestore dei messaggi del thread dell'interfaccia utente che consentono di inviare ed elaborare oggetti e messaggi eseguibili da altri thread .

Implementazione

AsyncTask è una classe generica. (Ci vogliono tipi con parametri nel suo costruttore.)

Utilizza questi tre tipi generici:

Params - il tipo di parametri inviati all'attività al momento dell'esecuzione.

Progress - il tipo di unità di progresso pubblicate durante il calcolo in background.

Result - il tipo del risultato del calcolo in background.

Non tutti i tipi sono sempre utilizzati da un'attività asincrona. Per contrassegnare un tipo come non utilizzato, utilizzare semplicemente il tipo Void:

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Questi tre parametri corrispondono a tre funzioni principali in cui è possibile ignorare AsyncTask:

  • doInBackground(Params...)
  • onProgressUpdate(Progress...)
  • onPostExecute(Result)

Per eseguire AsyncTask

  • Chiama execute()con i parametri da inviare all'attività in background.

Che succede

  1. Sul thread principale / UI , onPreExecute()viene chiamato.

    • Inizializzare qualcosa in questo thread. (Ad esempio, mostra una barra di avanzamento sull'interfaccia utente.)
  2. Su un thread in background , doInBackground(Params...)viene chiamato.

    • ( Paramssono stati passati via execute.)
    • Dove dovrebbe succedere l'attività di lunga durata.
    • È necessario eseguire l'override almeno doInBackground()per utilizzare AsyncTask.

    • Chiama publishProgress(Progress...)per aggiornare l'interfaccia utente con un display di avanzamento (ad esempio animazione dell'interfaccia utente o testo del registro stampato) mentre il calcolo in background è ancora in esecuzione.

      • Fa onProgressUpdate()chiamare.
  3. Sul thread in background viene restituito un risultato doInBackground().

    • (Questo innesca il passaggio successivo.)
  4. Sul thread principale / UI , onPostExecute()viene chiamato con il risultato restituito.

Esempi

In entrambi gli esempi il "task di blocco" è un download dal Web.

  • L'esempio A scarica un'immagine e la visualizza in ImageView, mentre
  • L'esempio B scarica alcuni file .

Esempio A

Il doInBackground()metodo scarica l'immagine e la memorizza in un oggetto di tipo BitMap. Il onPostExecute()metodo prende la bitmap e la inserisce in ImageView.

class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bitImage;

    public DownloadImageTask(ImageView bitImage) {
        this.bitImage = bitImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mBmp = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mBmp = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mBmp;
    }

    protected void onPostExecute(Bitmap result) {
        bitImage.setImageBitmap(result);
    }
}

Esempio B

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

Esecuzione dell'esempio B.

new DownloadFilesTask().execute(url1, url2, url3);

Molto bello .. Ma continuo a ricevere errori sullo scontro tra tipi di ritorno - tentando di usare un tipo di ritorno incompatibile. Ho provato tutti i tipi di tipi restituiti, stesso errore.
john ktejik,

Ciao @johnktejik, potresti voler cercare quel problema specifico. Forse è quello che ti sta succedendo: il tipo-ritorno-è-incompatibile-con-asincrono
TT--

1
Eccellente! Consideri di andare al montaggio ?
Peter Mortensen,

12

Quando viene eseguita un'attività asincrona, l'attività passa attraverso quattro passaggi:

  1. OnPreExecute ()
  2. doInBackground (Params ...)
  3. onProgressUpdate (Progress ...)
  4. OnPostExecute (Risultato)

Di seguito è riportato un esempio demo:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));

            // Escape early if cancel() is called
            if (isCancelled())
                break;
        }
        return totalSize;
    }

    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
 }

E una volta creato, un'attività viene eseguita in modo molto semplice:

new DownloadFilesTask().execute(url1, url2, url3);

execute si aspetta un paremeter come Runnable. Non accetta la stringa. Qual è il tipo di url? stringa o no

10

L'esempio più breve per fare semplicemente qualcosa in modo asincrono:

class MyAsyncTask extends android.os.AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        // Do something asynchronously
        return null;
    }
}

Per eseguirlo:

(new MyAsyncTask()).execute();

10

Come memorizzare i parametri utilizzati in AsyncTask?

non

Se non si conosce AsyncTask, è molto comune confondersi durante la scrittura di un AsyncTask. I principali colpevoli sono i parametri utilizzati in AsyncTask, ovvero AsyncTask<A, B, C>. Basato sulla firma A, B, C (argomenti) dei metodi differisce, il che rende le cose ancora più confuse.

Mantienilo semplice!

La chiave è non memorizzare . Se riesci a visualizzare ciò che il tuo compito deve realmente fare, scrivere l'AsyncTask con la firma corretta al primo tentativo sarebbe un gioco da ragazzi. Basta capire quali sono i tuoi Input, Progresse quali Outputsono, e sarai bravo ad andare.

Quindi cos'è un AsyncTask?

AsyncTask è un'attività in background che viene eseguita nel thread in background. Prende un Input, si esibisce Progresse dà un Output.

Vale a dire , AsyncTask<Input, Progress, Output>.

Per esempio:

Inserisci qui la descrizione dell'immagine

Qual è la relazione con i metodi?

Tra AsyncTaskedoInBackground()

Inserisci qui la descrizione dell'immagine

doInBackground()e onPostExecute(),onProgressUpdate () `sono anche correlati

Inserisci qui la descrizione dell'immagine

Come scriverlo nel codice?

DownloadTask extends AsyncTask<String, Integer, String>{

    // Always same signature
    @Override
    public void onPreExecute()
    {}

    @Override
    public String doInbackGround(String... parameters)
    {
        // Download code
        int downloadPerc = // Calculate that
        publish(downloadPerc);

        return "Download Success";
    }

    @Override
    public void onPostExecute(String result)
    {
        super.onPostExecute(result);
    }

    @Override
    public void onProgressUpdate(Integer... parameters)
    {
        // Show in spinner, and access UI elements
    }

}

Come eseguirai questa attività?

new DownLoadTask().execute("Paradise.mp3");

6

Quando sei nel thread di lavoro, non puoi manipolare direttamente gli elementi dell'interfaccia utente su Android.

Quando si utilizza AsyncTask, comprendere i metodi di richiamata.

Per esempio:

public class MyAyncTask extends AsyncTask<Void, Void, Void>{

    @Override
    protected void onPreExecute() {
        // Here you can show progress bar or something on the similar lines.
        // Since you are in a UI thread here.
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // After completing execution of given task, control will return here.
        // Hence if you want to populate UI elements with fetched data, do it here.
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        // You can track you progress update here
    }

    @Override
    protected Void doInBackground(Void... params) {
        // Here you are in the worker thread and you are not allowed to access UI thread from here.
        // Here you can perform network operations or any heavy operations you want.
        return null;
    }
}

FYI: per accedere al thread dell'interfaccia utente da un thread di lavoro, utilizzare il metodo runOnUiThread () o il metodo post nella vista.

Per esempio:

runOnUiThread(new Runnable() {
    textView.setText("something.");
});

or
    yourview.post(new Runnable() {
    yourview.setText("something");
});

Questo ti aiuterà a conoscere meglio le cose. Pertanto, nel tuo caso, devi impostare la visualizzazione del testo nel metodo onPostExecute ().



3

Esempio di attività asincrona con richiesta POST:

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();

class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
    String URL;
    List<NameValuePair> parameters;

    private ProgressDialog pDialog;

    public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
    {
        this.URL = url;
        this.parameters = params;
    }

    @Override
    protected void onPreExecute()
    {
        pDialog = new ProgressDialog(LoginActivity.this);
        pDialog.setMessage("Processing Request...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            HttpPost httpPost = new HttpPost(URL);

            if (parameters != null)
            {
                httpPost.setEntity(new UrlEncodedFormEntity(parameters));
            }
            httpResponse = httpClient.execute(httpPost);

            httpEntity = httpResponse.getEntity();
            return EntityUtils.toString(httpEntity);

        }  catch (Exception e)
        {

        }
        return "";
    }

    @Override
    protected void onPostExecute(String result)
    {
        pDialog.dismiss();

        try
        {

        }
        catch (Exception e)
        {

        }
        super.onPostExecute(result);
    }
}

1

Semplicemente:

LongOperation MyTask = new LongOperation();
MyTask.execute();

1

Devi dichiarare il pulsante onclicklistener. Una volta cliccato, chiama la classe AsyncTask DownloadJson.

Il processo verrà mostrato di seguito:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new DownloadJson().execute();
            }
        });
    }

    // DownloadJSON AsyncTask
    private class DownloadJson extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            newlist = new ArrayList<HashMap<String, String>>();
            json = jsonParser.makeHttpRequest(json, "POST");
            try {
                newarray = new JSONArray(json);
                    for (int i = 0; i < countdisplay; i++) {
                        HashMap<String, String> eachnew = new HashMap<String, String>();
                        newobject = newarray.getJSONObject(i);
                        eachnew.put("id", newobject.getString("ID"));
                        eachnew.put("name", newobject.getString("Name"));
                        newlist.add(eachnew);
                    }
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            newlisttemp.addAll(newlist);
            NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this, newlisttemp);
            newpager.setAdapter(newadapterpager);
        }
    }

1
private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Showing progress dialog
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... arg0) {

        // Do code here

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        // Dismiss the progress dialog
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    @Override
    protected void onCancelled() {

        super.onCancelled();
        progressDialog.dismiss();
        Toast toast = Toast.makeText(
                          getActivity(),
                          "An error is occurred due to some problem",
                          Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP, 25, 400);
        toast.show();
    }

}


0

Esempio di esempio di AsyncTask con avanzamento

import android.animation.ObjectAnimator;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {

    Button btn;
    ProgressBar progressBar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);
        progressBar = (ProgressBar)findViewById(R.id.pbar);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
                new LongOperation().execute("");
                break;
        }
    }

    private class LongOperation extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... params) {
            Log.d("AsyncTask", "doInBackground");
            for (int i = 0; i < 5; i++) {
                try {
                    Log.d("AsyncTask", "task "+(i + 1));
                    publishProgress(i + 1);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.interrupted();
                }
            }
            return "Completed";
        }

        @Override
        protected void onPostExecute(String result) {
            Log.d("AsyncTask", "onPostExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText(result);
            progressBar.setProgress(0);
        }

        @Override
        protected void onPreExecute() {
            Log.d("AsyncTask", "onPreExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onPreExecute");
            progressBar.setMax(500);
            progressBar.setProgress(0);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.d("AsyncTask", "onProgressUpdate "+values[0]);
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onProgressUpdate "+values[0]);

            ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100 * values[0]);
            animation.setDuration(1000);
            animation.setInterpolator(new LinearInterpolator());
            animation.start();
        }
    }
}

0

Task ASync;

public class MainActivity extends AppCompatActivity {

    private String ApiUrl = "your_api";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyTask myTask = new MyTask();
        try {
            String result=myTask.execute(ApiUrl).get();
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
           e.printStackTrace();
        }
    }

    public class MyTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {

            String result = "";
            HttpURLConnection httpURLConnection = null;
            URL url;

            try {
                url = new URL(strings[0]);
                httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);
                result = getData(reader);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }

        public String getData(InputStreamReader reader) throws IOException {

            String result = "";
            int data = reader.read();
            while (data!=-1) {
                char now = (char) data;
                result += data;
                data = reader.read();
            }
            return result;
        }
    }

}

Perché la classe è MyTaskdentro la classe MainActivity? È consuetudine?
Peter Mortensen,

0

Mentre lavori con AsyncTask, è necessario creare un successore di classe e in esso registrare l'implementazione dei metodi necessari per noi. In questa lezione vedremo tre metodi:

doInBackground - verrà eseguito in un nuovo thread e qui risolviamo tutti i nostri difficili compiti. Perché un thread non primario non ha accesso all'interfaccia utente.

onPreExecute : eseguito prima di doInBackground e ha accesso all'interfaccia utente

onPostExecute - eseguito dopo doInBackground (non funziona se AsyncTask è stato annullato - su questo nelle prossime lezioni) e ha accesso all'interfaccia utente.

Questa è la classe MyAsyncTask:

class MyAsyncTask extends AsyncTask<Void, Void, Void> {

  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    tvInfo.setText("Start");
  }

  @Override
  protected Void doInBackground(Void... params) {
    // Your background method
    return null;
  }

  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    tvInfo.setText("Finish");
  }
}

Ed ecco come chiamare la tua attività o frammento:

MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();

Ri "su questo nelle prossime lezioni" : a cosa si riferisce? Ad esempio, da dove viene preso questo?
Peter Mortensen,

0

se apri la classe AsyncTask puoi vedere sotto il codice.

public abstract class AsyncTask<Params, Progress, Result> {
    @WorkerThread
    protected abstract Result doInBackground(Params... params);
    @MainThread
    protected void onPreExecute() {
    }
    @SuppressWarnings({"UnusedDeclaration"})
    @MainThread
    protected void onPostExecute(Result result) {
    }
}

Funzionalità AsyncTask

  1. AsyncTask è una classe astratta
  2. AsyncTask ha 3 parametri generici.
  3. AsyncTask ha un metodo astratto di doInBackground, onPreExecute, onPostExecute
  4. doInBackground è WorkerThread (non è possibile aggiornare l'interfaccia utente)
  5. onPreExecute è MainThread
  6. onPostExecute è MainThread (è possibile aggiornare l'interfaccia utente)

esempio

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    mEmailView = (AutoCompleteTextView) findViewById(R.id.email);

    AsyncTask<Void, Void, Post> asyncTask = new AsyncTask<Void, Void, Post>() {
        @Override
        protected Post doInBackground(Void... params) {
            try {
                ApiClient defaultClient = Configuration.getDefaultApiClient();
                String authorization = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODIxMzM4MTB9.bA3Byc_SuB6jzqUGAY4Pyt4oBNg0VfDRctZ8-PcPlYg"; // String | JWT token for Authorization
                ApiKeyAuth Bearer = (ApiKeyAuth) defaultClient.getAuthentication("Bearer");
                Bearer.setApiKey(authorization);
                PostApi apiInstance = new PostApi();
                String id = "1"; // String | id
                Integer commentPage = 1; // Integer | Page number for Comment
                Integer commentPer = 10; // Integer | Per page number For Comment
                Post result;
                try {
                    result = apiInstance.apiV1PostsIdGet(id, authorization, commentPage, commentPer);
                } catch (ApiException e) {
                    e.printStackTrace();
                    result = new Post();
                }
                return result;
            } catch (Exception e) {
                e.printStackTrace();
                return new Post();
            }
        }

        @Override
        protected void onPostExecute(Post post) {
            super.onPostExecute(post);
            if (post != null) {
                mEmailView.setText(post.getBody());
                System.out.print(post);
            }
        }
    };
    asyncTask.execute();
}

-1

Modifica il codice come indicato di seguito:

@Override
protected void onPostExecute(String result) {

    runOnUiThread(new Runnable() {
        public void run() {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
        }
    });
}

1
Non dovresti aver bisogno di usare runOnUiThread come onPostExecute gira sempre sul thread 1 (no?)
justdan0227
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.