AsyncTask Android Beispiel


680

Ich habe darüber gelesen AsyncTaskund das einfache Programm unten ausprobiert. Aber es scheint nicht zu funktionieren. Wie kann ich es zum Laufen bringen?

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) {
        }
    }
}

Ich versuche nur, die Beschriftung nach 5 Sekunden im Hintergrund zu ändern.

Dies ist meine 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
Sie können den Fortschritt auch anzeigen, indem Sie Publishprogress () über die Methode doInBackground () aufrufen.
Osum

3
Hier ist Asynctask Beispiel AsyncTask Beispiel
Samir Mangroliya

Hier ist ein Asynctask-Beispiel für das Herunterladen von Bildern
Houcine


3
einfaches Beispiel ... Sie müssen Link
c49

Antworten:


702

Ok, Sie versuchen, über einen anderen Thread auf die GUI zuzugreifen. Dies ist im Wesentlichen keine gute Praxis.

Die AsyncTask führt alles in doInBackground()einem anderen Thread aus, der keinen Zugriff auf die GUI hat, auf der sich Ihre Ansichten befinden.

preExecute()und postExecute()bieten Ihnen Zugriff auf die GUI vor und nach dem schweren Heben in diesem neuen Thread, und Sie können sogar das Ergebnis der langen Operation an übergeben, postExecute()um dann alle Ergebnisse der Verarbeitung anzuzeigen.

Sehen Sie sich diese Zeilen an, in denen Sie später Ihre Textansicht aktualisieren:

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

Setzen Sie sie ein onPostExecute().

Nach Abschluss des Vorgangs wird der TextView-Text aktualisiert doInBackground.

Ich habe festgestellt, dass Ihr onClick-Listener nicht überprüft, welche Ansicht ausgewählt wurde. Ich finde den einfachsten Weg, dies zu tun, über switch-Anweisungen. Ich habe eine vollständige Klasse unten mit allen Vorschlägen bearbeitet, um Verwirrung zu vermeiden.

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
Ich kann dies nicht tun <code> btn.setOnClickListener (this); </ code> Eclipse gibt einen Fehler aus ----- "Die Methode setOnClickListener (View.OnClickListener) im Typ View gilt nicht für die Argumente (AsyncTaskActivity)"
Fox

Ich würde empfehlen, die Einstellung des Textes so zu ändern, dass sie nicht statisch ist, sondern das Argument aus der onPostExecute(String result)Methode zu übernehmen. Dies würde zukünftigen Lesern klarer machen, dass das Argument mit dem Rückgabewert von gefüllt ist doInBackground(String... params).
Eric

@ Eric Tobias - Genau das haben die Dinge bereits im kommentierten Bereich getan. Ich habe die Benutzerfrage in meinem vollständigen Beispiel verfolgt und beantwortet.
Graham Smith

1
Als Nachtrag und Google Seeder (und von jemandem, der gerade dieses Zeug lernt, wie ich darauf gestoßen bin): Die meisten UI-Updates, die Sie für etwas durchführen, bei dem Sie dem Benutzer gemeldete Fortschritte benötigen, befinden sich im Rückruf onProgressUpdate Dies wird im Haupt-UI-Thread ausgeführt.
RichieHH

1
Dies wird sicherlich durcheinander bringen, wenn Ihre Aktivität aus irgendeinem Grund gedreht oder zerstört wird ...
Sam

792

Meine vollständige Antwort ist hier , aber hier ist ein erklärendes Bild, um die anderen Antworten auf dieser Seite zu ergänzen. Für mich war es am Anfang am verwirrendsten zu verstehen, wohin alle Variablen gingen.

Geben Sie hier die Bildbeschreibung ein


3
paramsist ein Array. (Im obigen Beispiel war es ein StringArray.) Auf diese Weise können Sie mehrere Parameter desselben Typs übergeben. Dann können Sie diese Parameter zugreifen mit params[0], params[1], params[2]usw. In dem Beispiel gab es nur eine einzige Stringin dem paramsArray. Wenn Sie mehrere Parameter unterschiedlichen Typs übergeben müssen (z. B. a Stringund an int), lesen Sie diese Frage .
Suragch

73

Ich bin sicher, dass es ordnungsgemäß ausgeführt wird, aber Sie versuchen, die UI-Elemente im Hintergrund-Thread zu ändern, und das reicht nicht aus.

Überarbeiten Sie Ihren Anruf und AsyncTask wie folgt:

Klasse anrufen

Hinweis: Ich persönlich empfehle, onPostExecute()überall dort zu verwenden, wo Sie Ihren AsyncTask-Thread ausführen, und nicht in der Klasse, die AsyncTask selbst erweitert. Ich denke, es erleichtert das Lesen des Codes, insbesondere wenn Sie die AsyncTask an mehreren Stellen benötigen, um die Ergebnisse leicht unterschiedlich zu behandeln.

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

LongThread-Klasse (erweitert 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
Vielen Dank für die Bereitstellung eines Beispiels, das die AsyncTask von der Aktivität entkoppelt
sthomps

1
ja, endlich entkoppelt jemand die aufgabe und die aktivität. Vielen Dank. Und das Überschreiben der onPostExecutein der Aktivität ist brillant.
mcy

58

Konzept und Code hier

Ich habe ein einfaches Beispiel für die Verwendung von AsyncTask von Android erstellt. Es beginnt mit onPreExecute(), doInBackground(), publishProgress()und schließlich onProgressUpdate().

In diesem Fall fungiert doInBackground () als Hintergrundthread, während andere im UI-Thread arbeiten. Sie können in doInBackground () nicht auf ein UI-Element zugreifen. Die Reihenfolge ist die gleiche wie ich erwähnt habe.

Wenn Sie jedoch müssen von jeder Widget aktualisieren doInBackground, können Sie publishProgressaus doInBackgrounddem rufen onProgressUpdateIhre UI - Widget zu aktualisieren.

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

Nennen Sie es in Ihrer Aktivität so:

new TestAsync().execute();

Entwicklerreferenz hier


3
Der Unterricht beginnt in der Regel mit Großbuchstaben in Java.
Diese

20

Verschieben Sie diese beiden Zeilen:

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

aus der AsyncTask- doInBackgroundMethode und fügen Sie sie in die onPostExecuteMethode ein. Du AsyncTasksolltest ungefähr so ​​aussehen:

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

Hey, was ich als asynchrone Aufgabe im Dienst ausführe, ich möchte einen Wert an den Haupt-UI-Thread zurückgeben.
Dipen

@Dipen - Schauen Sie sich diese Diskussion an . Es gibt zwei Probleme: Berichterstattung über Ergebnisse von a AsyncTask, auf die sich meine Antwort bezieht; und Senden eines Werts von einem Dienst an den UI-Thread, den die andere Diskussion anspricht. Diese Fragen sind unabhängig.
Ted Hopp

14

Hintergrund / Theorie

Mit AsyncTask können Sie eine Aufgabe in einem Hintergrundthread ausführen und gleichzeitig Ergebnisse im UI-Thread veröffentlichen.

Der Benutzer sollte immer in der Lage sein, mit der App zu interagieren. Daher ist es wichtig , das Blockieren des Hauptthreads (UI) bei Aufgaben wie dem Herunterladen von Inhalten aus dem Web zu vermeiden .

Deshalb verwenden wir eine AsyncTask.

Es bietet eine unkomplizierte Benutzeroberfläche, indem die Warteschlange und der Handler für UI-Thread-Nachrichten umbrochen werden, mit denen Sie ausführbare Objekte und Nachrichten von anderen Threads senden und verarbeiten können .

Implementierung

AsyncTask ist eine generische Klasse. ( In seinem Konstruktor werden parametrisierte Typen verwendet.)

Es werden diese drei generischen Typen verwendet:

Params - die Art der Parameter, die bei der Ausführung an die Task gesendet werden.

Progress - die Art der Fortschrittseinheiten, die während der Hintergrundberechnung veröffentlicht wurden.

Result - die Art des Ergebnisses der Hintergrundberechnung.

Nicht alle Typen werden immer von einer asynchronen Aufgabe verwendet. Um einen Typ als nicht verwendet zu markieren, verwenden Sie einfach den Typ Void:

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

Diese drei Parameter entsprechen drei Hauptfunktionen, die Sie überschreiben können AsyncTask:

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

So führen Sie AsyncTask aus

  • Aufruf execute()mit Parametern, die an die Hintergrundaufgabe gesendet werden sollen.

Was geschieht

  1. Auf main / UI - Thread , onPreExecute()wird aufgerufen.

    • Um etwas in diesem Thread zu initialisieren. (ZB einen Fortschrittsbalken auf der Benutzeroberfläche anzeigen.)
  2. Auf einem Hintergrund - Thread , doInBackground(Params...)wird aufgerufen.

    • ( Paramswurden über übergeben execute.)
    • Wo die langfristige Aufgabe stattfinden soll.
    • Muss mindestens überschrieben werden doInBackground(), um AsyncTask zu verwenden.

    • Rufen Sie publishProgress(Progress...)an, um die Benutzeroberfläche mit einer Fortschrittsanzeige (z. B. UI-Animation oder gedruckter Protokolltext) zu aktualisieren, während die Hintergrundberechnung noch ausgeführt wird.

      • Ursachen onProgressUpdate()zum Aufrufen.
  3. Im Hintergrund-Thread wird ein Ergebnis von zurückgegeben doInBackground().

    • (Dies löst den nächsten Schritt aus.)
  4. Auf main / UI - Thread , onPostExecute()wird mit dem zurückgegebenen Ergebnis genannt.

Beispiele

In beiden Beispielen ist die "Blockierungsaufgabe" ein Download aus dem Web.

  • Beispiel A lädt ein Bild herunter und zeigt es in einer ImageView an
  • Beispiel B lädt einige Dateien herunter .

Beispiel A.

Die doInBackground()Methode lädt das Bild herunter und speichert es in einem Objekt vom Typ BitMap. Die onPostExecute()Methode nimmt die Bitmap und platziert sie in der 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);
    }
}

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

Beispiel B Ausführung

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

Sehr schön. Aber ich erhalte immer wieder Fehler bezüglich der Kollision von Rückgabetypen - ich versuche, einen inkompatiblen Rückgabetyp zu verwenden. Ich habe alle Arten von Rückgabetypen ausprobiert, den gleichen Fehler.
John Ktejik

Hallo @johnktejik, vielleicht möchten Sie nach diesem speziellen Problem suchen. Vielleicht passiert Ihnen Folgendes
TT

1
Ausgezeichnet! Überlegen Sie, in die Bearbeitung zu gehen ?
Peter Mortensen

12

Wenn eine asynchrone Aufgabe ausgeführt wird, durchläuft die Aufgabe vier Schritte:

  1. onPreExecute ()
  2. doInBackground (Params ...)
  3. onProgressUpdate (Fortschritt ...)
  4. onPostExecute (Ergebnis)

Unten finden Sie ein Demo-Beispiel:

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

Und sobald Sie erstellt haben, wird eine Aufgabe ganz einfach ausgeführt:

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

execute erwartet einen Parameter als Runnable. Es akzeptiert keine Zeichenfolge. Was ist die Art Ihrer URL? Zeichenfolge oder nicht

10

Das kürzeste Beispiel dafür, wie man etwas asynchron macht:

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

Um es auszuführen:

(new MyAsyncTask()).execute();

10

Wie werden die in AsyncTask verwendeten Parameter gespeichert?

Tu es nicht

Wenn Sie AsyncTask noch nicht kennen, kann es beim Schreiben einer AsyncTask häufig zu Verwirrung kommen. Die Hauptschuldigen sind die in der AsyncTask verwendeten Parameter, d AsyncTask<A, B, C>. H. Basierend auf der A-, B-, C- Signatur (Argumente) unterscheiden sich die Methoden, was die Dinge noch verwirrender macht.

Halte es einfach!

Der Schlüssel ist nicht auswendig lernen . Wenn Sie sich vorstellen können, was Ihre Aufgabe wirklich zu tun hat, ist das Schreiben der AsyncTask mit der richtigen Signatur beim ersten Versuch ein Kinderspiel. Nur herauszufinden , was Ihre Input, Progressund Outputsind, und Sie werden gut zu gehen.

Was ist eine AsyncTask?

AsyncTask ist eine Hintergrundaufgabe, die im Hintergrundthread ausgeführt wird. Es dauert eine Input, führt Progressund gibt eine Output.

Dh , AsyncTask<Input, Progress, Output>.

Zum Beispiel:

Geben Sie hier die Bildbeschreibung ein

Wie ist die Beziehung zu Methoden?

Zwischen AsyncTaskunddoInBackground()

Geben Sie hier die Bildbeschreibung ein

doInBackground()und onPostExecute(),onProgressUpdate () `sind ebenfalls verwandt

Geben Sie hier die Bildbeschreibung ein

Wie schreibe ich das in den Code?

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
    }

}

Wie werden Sie diese Aufgabe ausführen?

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

6

Wenn Sie sich im Worker-Thread befinden, können Sie UI-Elemente unter Android nicht direkt bearbeiten.

Wenn Sie AsyncTask verwenden, verstehen Sie bitte die Rückrufmethoden.

Zum Beispiel:

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;
    }
}

Zu Ihrer Information: Um von einem Arbeitsthread aus auf den UI-Thread zuzugreifen, verwenden Sie entweder die runOnUiThread () -Methode oder die post-Methode in Ihrer Ansicht.

Zum Beispiel:

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

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

Dies wird Ihnen helfen, die Dinge besser zu kennen. Daher müssen Sie in Ihrem Fall Ihre Textansicht in der onPostExecute () -Methode festlegen.


5

Ich würde empfehlen, Ihnen das Leben zu erleichtern, indem Sie diese Bibliothek für Hintergrundarbeiten verwenden:

https://github.com/Arasthel/AsyncJobLibrary

So einfach ist das ...

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {

    @Override
    public void doOnBackground() {
        startRecording();
    }
});

3

Beispiel für eine asynchrone Aufgabe mit POST-Anforderung:

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

Sie müssen die Schaltfläche onclicklistener deklarieren. Nach dem Klicken wird die AsyncTask-Klasse DownloadJson aufgerufen.

Der Prozess wird unten gezeigt:

@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

Beispiel für ein AsyncTask-Beispiel mit Fortschritt

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

ASync-Aufgabe;

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;
        }
    }

}

Warum ist Klasse MyTaskin Klasse MainActivity? Ist das üblich?
Peter Mortensen

0

Während der Arbeit mit AsyncTask ist es erforderlich, einen Klassennachfolger zu erstellen und darin die Implementierung der für uns erforderlichen Methoden zu registrieren. In dieser Lektion werden drei Methoden betrachtet:

doInBackground - wird in einem neuen Thread ausgeführt und hier lösen wir alle unsere schwierigen Aufgaben. Weil ein nicht primärer Thread keinen Zugriff auf die Benutzeroberfläche hat.

onPreExecute - wird vor doInBackground ausgeführt und hat Zugriff auf die Benutzeroberfläche

onPostExecute - wird nach doInBackground ausgeführt (funktioniert nicht, wenn AsyncTask abgebrochen wurde - dies in den nächsten Lektionen) und hat Zugriff auf die Benutzeroberfläche.

Dies ist die MyAsyncTask-Klasse:

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

Und so rufen Sie Ihre Aktivität oder Ihr Fragment auf:

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

Zu "darüber in den nächsten Lektionen" : Worauf bezieht sich das? ZB woher kommt das?
Peter Mortensen

0

Wenn Sie die AsyncTask-Klasse öffnen, sehen Sie den folgenden Code.

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) {
    }
}

AsyncTask-Funktionen

  1. AsyncTask ist eine abstrakte Klasse
  2. AsyncTask hat 3 generische Parameter.
  3. AsyncTask verfügt über die abstrakte Methode doInBackground, onPreExecute, onPostExecute
  4. doInBackground ist WorkerThread (Sie können die Benutzeroberfläche nicht aktualisieren)
  5. onPreExecute ist MainThread
  6. onPostExecute ist MainThread (Sie können die Benutzeroberfläche aktualisieren)

Beispiel

@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

Ändern Sie Ihren Code wie folgt:

@Override
protected void onPostExecute(String result) {

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

1
Sie sollten runOnUiThread nicht verwenden müssen, da onPostExecute immer auf Thread 1 ausgeführt wird (nicht
wahr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.