Suche…


Parameter

Parameter Einzelheiten
Params die Art der Parameter, die bei der Ausführung an die Task gesendet werden.
Fortschritt die Art der Fortschrittseinheiten, die während der Hintergrundberechnung veröffentlicht wurden
Ergebnis die Art des Ergebnisses der Hintergrundberechnung.

Grundlegende Verwendung

In Android Aktivitäten und Dienstleistungen sind die meisten Rückrufe auf der Flucht Hauptthread . Dies macht es einfach, die Benutzeroberfläche zu aktualisieren, aber das Ausführen von prozessor- oder E / A-schweren Tasks im Haupt-Thread kann dazu führen, dass Ihre Benutzeroberfläche angehalten wird und nicht mehr reagiert ( offizielle Dokumentation dazu, was dann passiert).

Sie können dies beheben, indem Sie diese schwereren Aufgaben in einem Hintergrundthread ablegen.

Eine Möglichkeit hierzu ist die Verwendung einer AsyncTask , die ein Framework bereitstellt , das die einfache Verwendung eines Hintergrund-Threads erleichtert und UI-Thread-Tasks vor, während und nach Abschluss der Arbeit des Hintergrund-Threads ausführt.

Methoden, die beim Erweitern von AsyncTask überschrieben werden AsyncTask :

  • onPreExecute() : onPreExecute() im UI-Thread aufgerufen, bevor die Task ausgeführt wird
  • doInBackground() : auf dem Hintergrund - Thread aufgerufen unmittelbar nach onPreExecute() beendet die Ausführung.
  • onProgressUpdate() : onProgressUpdate() nach einem Aufruf von publishProgress(Progress...) im UI-Thread aufgerufen.
  • onPostExecute() : onPostExecute() im UI-Thread aufgerufen, nachdem die Hintergrundberechnung abgeschlossen ist

Beispiel

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

}

Verwendungszweck:

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

oder einfach:

new MyCustomAsyncTask().execute(userSuppliedFilename);

Hinweis

Bei der Definition einer AsyncTask wir drei Typen zwischen < > Klammern übergeben.
Definiert als <Params, Progress, Result> (siehe Abschnitt Parameter )

Im vorherigen Beispiel haben wir die Typen <File, Void, String> :

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

Void wird verwendet, wenn Sie einen Typ als nicht verwendet markieren möchten.

Beachten Sie, dass Sie keine primitiven Typen (dh int , float und 6 andere) als Parameter übergeben können. In solchen Fällen sollten Sie ihre Wrapper-Klassen übergeben , z. B. Integer statt int oder Float statt float .

Der AsyncTask- und Activity-Lebenszyklus

AsyncTasks folgen nicht dem Lebenszyklus der Aktivitätsinstanzen. Wenn Sie eine AsyncTask in einer Aktivität starten und das Gerät drehen, wird die Aktivität zerstört und eine neue Instanz erstellt. Aber die AsyncTask wird nicht sterben. Es wird weiterleben, bis es fertig ist.

Lösung: AsyncTaskLoader

Eine Unterklasse von Loadern ist der AsyncTaskLoader. Diese Klasse hat die gleiche Funktion wie die AsyncTask, jedoch viel besser. Es kann Aktivitätskonfigurationsänderungen einfacher handhaben und verhält sich innerhalb der Lebenszyklen von Fragmenten und Aktivitäten. Das Schöne ist, dass der AsyncTaskLoader in jeder Situation verwendet werden kann, in der die AsyncTask verwendet wird. Immer wenn Daten in den Speicher geladen werden müssen, damit die Aktivität / das Fragment verarbeitet werden kann, kann der AsyncTaskLoader die Aufgabe besser erfüllen.

AsyncTask abbrechen

YourAsyncTask task = new YourAsyncTask();
task.execute();
task.cancel();

Dies stoppt Ihre Aufgabe nicht, wenn sie gerade ausgeführt wird. Sie setzt lediglich das Flag " isCancelled() das überprüft werden kann, indem der Rückgabewert von isCancelled() überprüft wird (vorausgesetzt, Ihr Code läuft derzeit).

class YourAsyncTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        while(!isCancelled()) {
            ... doing long task stuff
            //Do something, you need, upload part of file, for example
            if (isCancelled()) {    
                return null; // Task was detected as canceled
            }
            if (yourTaskCompleted) {
                return null;
            }
        }
    }
}

Hinweis

Wenn eine AsyncTask abgebrochen wird, während noch doInBackground(Params... params) wird, wird die Methode onPostExecute(Result result) NICHT nach doInBackground(Params... params) . Die AsyncTask ruft stattdessen onCancelled(Result result) auf, um anzuzeigen, dass die Aufgabe während der Ausführung abgebrochen wurde.

Veröffentlichungsfortschritt

Manchmal müssen wir den Fortschritt der von einer AsyncTask Berechnung AsyncTask . Dieser Fortschritt kann durch eine Zeichenfolge, eine Ganzzahl usw. dargestellt werden. Dazu müssen wir zwei Funktionen verwenden. Zuerst müssen wir die onProgressUpdate Funktion onProgressUpdate , deren Parametertyp dem zweiten Typparameter unserer AsyncTask .

class YourAsyncTask extends AsyncTask<URL, Integer, Long> {
    @Override
    protected void onProgressUpdate(Integer... args) {
        setProgressPercent(args[0])
    }
}

Zweitens müssen wir die Funktion publishProgress notwendigerweise auf der doInBackground Funktion, und das ist alles, tun die vorherige Methode alle den Job.

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

Laden Sie das Bild mit AsyncTask in Android herunter

In diesem Lernprogramm wird erläutert, wie Sie Image mit AsyncTask in Android herunterladen. Das Beispiel unten zeigt ein Bild zum Herunterladen, während der Download während des Fortschritts angezeigt wird.

Grundlegendes zu Android AsyncTask

Mit der asynchronen Task können Sie MultiThreading implementieren, ohne die Hände in Threads zu verschmutzen. AsyncTask ermöglicht die ordnungsgemäße und einfache Verwendung des UI-Threads. Es ermöglicht Hintergrundoperationen und die Weitergabe der Ergebnisse an den UI-Thread. Wenn Sie etwas Isoliertes in Bezug auf die Benutzeroberfläche tun, beispielsweise Daten herunterladen, um sie in einer Liste anzuzeigen, fahren Sie fort und verwenden Sie AsyncTask.

  • AsyncTasks sollten idealerweise für kurze Operationen (höchstens einige Sekunden) verwendet werden.
  • Eine asynchrone Task wird durch 3 generische Typen definiert, die als Params, Progress und Result bezeichnet werden, sowie 4 Schritte, die als onPreExecute() , doInBackground() , onProgressUpdate() und onPostExecute() .
  • In onPreExecute() Sie Code definieren, der ausgeführt werden muss, bevor die Hintergrundverarbeitung beginnt.
  • doInBackground enthält Code, der im Hintergrund ausgeführt werden muss. Hier in doInBackground() wir die Ergebnisse mit der Methode publishProgress () mehrmals an den Ereignisthread senden. Wenn die Hintergrundverarbeitung abgeschlossen ist, können wir die Ergebnisse einfach zurückgeben.
  • onProgressUpdate() Methode empfängt Fortschrittsaktualisierungen von der Methode doInBackground() , die über die publishProgress() Methode veröffentlicht wird. Diese Methode kann diese Fortschrittsaktualisierung zum Aktualisieren des Ereignisthreads verwenden
  • onPostExecute() -Methode verarbeitet Ergebnisse, die von der doInBackground() -Methode zurückgegeben werden.
  • Die generischen Typen sind
    • Params, der Typ der Parameter, die bei der Ausführung an die Task gesendet werden
    • Fortschritt, der Typ der Fortschrittseinheiten, die während der Hintergrundberechnung veröffentlicht wurden.
    • Result ist die Art des Ergebnisses der Hintergrundberechnung.
  • Wenn ein asynchroner Task keine Typen verwendet, kann er als ungültiger Typ markiert werden.
  • Eine laufende async-Task kann abgebrochen werden, indem cancel(boolean) Methode cancel(boolean) wird.

Bild mit Android AsyncTask herunterladen

Ihr XML-Layout

<?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" >

<Button
    android:id="@+id/downloadButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Click Here to Download" />

<ImageView
    android:id="@+id/imageView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:contentDescription="Your image will appear here" />

</LinearLayout>

.java-Klasse

package com.javatechig.droid;

import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class ImageDownladerActivity extends Activity {

    private ImageView downloadedImg;
    private ProgressDialog simpleWaitDialog;
    private String downloadUrl = "http://www.9ori.com/store/media/images/8ab579a656.jpg";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.asynch);
        Button imageDownloaderBtn = (Button) findViewById(R.id.downloadButton);

        downloadedImg = (ImageView) findViewById(R.id.imageView);

        imageDownloaderBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                new ImageDownloader().execute(downloadUrl);
            }

        });
    }

    private class ImageDownloader extends AsyncTask {

        @Override
        protected Bitmap doInBackground(String... param) {
            // TODO Auto-generated method stub
            return downloadBitmap(param[0]);
        }

        @Override
        protected void onPreExecute() {
            Log.i("Async-Example", "onPreExecute Called");
            simpleWaitDialog = ProgressDialog.show(ImageDownladerActivity.this,
                    "Wait", "Downloading Image");

        }

        @Override
        protected void onPostExecute(Bitmap result) {
            Log.i("Async-Example", "onPostExecute Called");
            downloadedImg.setImageBitmap(result);
            simpleWaitDialog.dismiss();

        }

        private Bitmap downloadBitmap(String url) {
            // initilize the default HTTP client object
            final DefaultHttpClient client = new DefaultHttpClient();

            //forming a HttpGet request 
            final HttpGet getRequest = new HttpGet(url);
            try {

                HttpResponse response = client.execute(getRequest);

                //check 200 OK for success
                final int statusCode = response.getStatusLine().getStatusCode();

                if (statusCode != HttpStatus.SC_OK) {
                    Log.w("ImageDownloader", "Error " + statusCode + 
                            " while retrieving bitmap from " + url);
                    return null;

                }

                final HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream inputStream = null;
                    try {
                        // getting contents from the stream 
                        inputStream = entity.getContent();

                        // decoding stream data back into image Bitmap that android understands
                        final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                        return bitmap;
                    } finally {
                        if (inputStream != null) {
                            inputStream.close();
                        }
                        entity.consumeContent();
                    }
                }
            } catch (Exception e) {
                // You Could provide a more explicit error message for IOException
                getRequest.abort();
                Log.e("ImageDownloader", "Something went wrong while" +
                        " retrieving bitmap from " + url + e.toString());
            } 

            return null;
        }
    }
}

Da es derzeit kein Kommentarfeld für Beispiele gibt (oder ich habe es nicht gefunden oder ich habe keine Erlaubnis dafür), hier ein Kommentar dazu:

Dies ist ein gutes Beispiel für die Verwendung von AsyncTask.

Allerdings hat das Beispiel derzeit Probleme mit

  • mögliche Speicherlecks
  • App stürzt ab, wenn kurz vor Beendigung der asynchronen Task eine Bildschirmrotation stattgefunden hat.

Für Details siehe:

Übergeben Sie die Aktivität als WeakReference, um Speicherverluste zu vermeiden

Es ist üblich, dass eine AsyncTask einen Verweis auf die Aktivität erfordert, die sie aufgerufen hat.

Wenn die AsyncTask eine innere Klasse der Aktivität ist, können Sie direkt auf sie und alle Member-Variablen / -Methoden verweisen.

Wenn die AsyncTask jedoch keine innere Klasse der Aktivität ist, müssen Sie eine Aktivitätsreferenz an die AsyncTask übergeben. Wenn Sie dies tun, besteht ein mögliches Problem möglicherweise darin, dass die AsyncTask den Verweis der Aktivität behält, bis die AsyncTask ihre Arbeit in ihrem Hintergrundthread abgeschlossen hat. Wenn die Aktivität beendet oder beendet wird, bevor die Hintergrundarbeit des AsyncTask-Threads abgeschlossen ist, hat die AsyncTask immer noch ihren Verweis auf die Aktivität. Daher kann keine Sammlung von Speicherbereinigungen erfolgen.

Dies führt zu einem Speicherverlust.

Um dies zu verhindern, verwenden Sie eine WeakReference in der AsyncTask, anstatt einen direkten Verweis auf die Aktivität zu haben.

Hier ist ein Beispiel für AsyncTask, das eine WeakReference verwendet:

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

    private WeakReference<Activity> mActivity;

    public MyAsyncTask(Activity activity) {
        mActivity = new WeakReference<Activity>(activity);
    }

    @Override
    protected void onPreExecute() {
        final Activity activity = mActivity.get();
        if (activity != null) {
            ....
        }
    }

    @Override
    protected Void doInBackground(String... params) {
        //Do something
        String param1 = params[0];
        String param2 = params[1];
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        final Activity activity = mActivity.get();
        if (activity != null) {
            activity.updateUI();
        }
    }
} 

AsyncTask aus einer Aktivität aufrufen:

new MyAsyncTask(this).execute("param1", "param2");

AsyncTask aus einem Fragment aufrufen:

new MyAsyncTask(getActivity()).execute("param1", "param2");

Reihenfolge der Ausführung

Bei der ersten Einführung wurden AsyncTasks seriell in einem einzigen Hintergrundthread ausgeführt. Beginnend mit DONUT wurde dies in einen Pool von Threads geändert, sodass mehrere Aufgaben parallel ausgeführt werden können. Beginnend mit HONEYCOMB werden Aufgaben in einem einzelnen Thread ausgeführt, um häufige Anwendungsfehler zu vermeiden, die durch die parallele Ausführung verursacht werden.

Wenn Sie wirklich eine parallele Ausführung wünschen, können Sie den executeOnExecutor(java.util.concurrent.Executor, Object[]) mit THREAD_POOL_EXECUTOR .

SERIAL_EXECUTOR -> Ein Executor, der Aufgaben nacheinander in serieller Reihenfolge ausführt.

THREAD_POOL_EXECUTOR -> Ein Executor, mit dem Aufgaben parallel ausgeführt werden können.

Probe :

Task task = new Task();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, data);
else
    task.execute(data);

AsyncTask: Serienausführung und parallele Ausführung der Aufgabe

AsyncTask ist eine abstrakte Klasse und erbt nicht die Thread Klasse. Es verfügt über eine abstrakte Methode doInBackground(Params... params) , die zur Ausführung der Aufgabe überschrieben wird. Diese Methode wird aus AsyncTask.call() aufgerufen.

Executor sind Teil des Pakets java.util.concurrent .

Außerdem enthält AsyncTask 2 Executor Dateien

THREAD_POOL_EXECUTOR

Es verwendet Worker-Threads, um die Aufgaben parallel auszuführen.

public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

SERIAL_EXECUTOR

Er führt die Aufgabe seriell aus, dh eine nach der anderen.

private static class SerialExecutor implements Executor { }

Beide Executor THREAD_POOL_EXECUTOR sind statisch , daher gibt es nur ein THREAD_POOL_EXECUTOR und ein SerialExecutor Objekt. Sie können jedoch mehrere AsyncTask Objekte erstellen.

Wenn Sie versuchen, mehrere Hintergrundaufgaben mit dem Standard-Executor ( SerialExecutor ) SerialExecutor , werden diese Aufgaben in die Warteschlange gestellt und seriell ausgeführt.

Wenn Sie versuchen, mehrere Hintergrundaufgaben mit THREAD_POOL_EXECUTOR , werden diese parallel ausgeführt.

Beispiel:

public class MainActivity extends Activity {
    private Button bt;
    private int CountTask = 0;
    private static final String TAG = "AsyncTaskExample";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt = (Button) findViewById(R.id.button);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BackgroundTask backgroundTask = new BackgroundTask ();
                Integer data[] = { ++CountTask, null, null };

                // Task Executed in thread pool ( 1 )
                backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, data);

                // Task executed Serially ( 2 )
                // Uncomment the below code and comment the above code of Thread
                // pool Executor and check
                // backgroundTask.execute(data);
                Log.d(TAG, "Task = " + (int) CountTask + " Task Queued");

            }
        });

    }

    private class BackgroundTask extends AsyncTask<Integer, Integer, Integer> {
        int taskNumber;

        @Override
        protected Integer doInBackground(Integer... integers) {
            taskNumber = integers[0];

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Log.d(TAG, "Task = " + taskNumber + " Task Running in Background");

            publishProgress(taskNumber);
            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Integer aLong) {
            super.onPostExecute(aLong);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            Log.d(TAG, "Task = " + (int) values[0]
                    + " Task Execution Completed");
        }
    }
}

Ausführen Klicken Sie mehrmals auf die Schaltfläche, um eine Aufgabe zu starten und das Ergebnis anzuzeigen.

Im Thread-Pool ausgeführte Aufgabe (1)

Jede Aufgabe dauert 1000 ms.

Bei t = 36s werden die Aufgaben 2, 3 und 4 in die Warteschlange gestellt und gestartet, auch weil sie parallel ausgeführt werden.

08-02 19:48:35.815: D/AsyncTaskExample(11693): Task = 1 Task Queued
08-02 19:48:35.815: D/AsyncTaskExample(11693): Task = 1 Task Running in Background
08-02 19:48:**36.025**: D/AsyncTaskExample(11693): Task = 2 Task Queued
08-02 19:48:**36.025**: D/AsyncTaskExample(11693): Task = 2 Task Running in Background
08-02 19:48:**36.165**: D/AsyncTaskExample(11693): Task = 3 Task Queued
08-02 19:48:**36.165**: D/AsyncTaskExample(11693): Task = 3 Task Running in Background
08-02 19:48:**36.325**: D/AsyncTaskExample(11693): Task = 4 Task Queued
08-02 19:48:**36.325**: D/AsyncTaskExample(11693): Task = 4 Task Running in Background
08-02 19:48:**36.815**: D/AsyncTaskExample(11693): Task = 1 Task Execution Completed
08-02 19:48:**36.915**: D/AsyncTaskExample(11693): Task = 5 Task Queued
08-02 19:48:**36.915**: D/AsyncTaskExample(11693): Task = 5 Task Running in Background
08-02 19:48:37.025: D/AsyncTaskExample(11693): Task = 2 Task Execution Completed
08-02 19:48:37.165: D/AsyncTaskExample(11693): Task = 3 Task Execution Completed
----------

Kommentar- Task Executed in thread pool (1) ausgeführt wird, und uncomment Task executed Serially (2).

Ausführen Klicken Sie mehrmals auf die Schaltfläche, um eine Aufgabe zu starten und das Ergebnis anzuzeigen.

Die Aufgabe wird seriell ausgeführt, daher wird jede Aufgabe gestartet, nachdem die Ausführung der aktuellen Aufgabe abgeschlossen ist. Wenn die Ausführung von Task 1 abgeschlossen ist, wird daher nur Task 2 im Hintergrund ausgeführt. Und umgekehrt.

08-02 19:42:57.505: D/AsyncTaskExample(10299): Task = 1 Task Queued
08-02 19:42:57.505: D/AsyncTaskExample(10299): Task = 1 Task Running in Background
08-02 19:42:57.675: D/AsyncTaskExample(10299): Task = 2 Task Queued
08-02 19:42:57.835: D/AsyncTaskExample(10299): Task = 3 Task Queued
08-02 19:42:58.005: D/AsyncTaskExample(10299): Task = 4 Task Queued
08-02 19:42:58.155: D/AsyncTaskExample(10299): Task = 5 Task Queued
08-02 19:42:58.505: D/AsyncTaskExample(10299): Task = 1 Task Execution Completed
08-02 19:42:58.505: D/AsyncTaskExample(10299): Task = 2 Task Running in Background
08-02 19:42:58.755: D/AsyncTaskExample(10299): Task = 6 Task Queued
08-02 19:42:59.295: D/AsyncTaskExample(10299): Task = 7 Task Queued
08-02 19:42:59.505: D/AsyncTaskExample(10299): Task = 2 Task Execution Completed
08-02 19:42:59.505: D/AsyncTaskExample(10299): Task = 3 Task Running in Background
08-02 19:43:00.035: D/AsyncTaskExample(10299): Task = 8 Task Queued
08-02 19:43:00.505: D/AsyncTaskExample(10299): Task = 3 Task Execution Completed
08-02 19:43:**00.505**: D/AsyncTaskExample(10299): Task = 4 Task Running in Background
08-02 19:43:**01.505**: D/AsyncTaskExample(10299): Task = 4 Task Execution Completed
08-02 19:43:**01.515**: D/AsyncTaskExample(10299): Task = 5 Task Running in Background
08-02 19:43:**02.515**: D/AsyncTaskExample(10299): Task = 5 Task Execution Completed
08-02 19:43:**02.515**: D/AsyncTaskExample(10299): Task = 6 Task Running in Background
08-02 19:43:**03.515**: D/AsyncTaskExample(10299): Task = 7 Task Running in Background
08-02 19:43:**03.515**: D/AsyncTaskExample(10299): Task = 6 Task Execution Completed
08-02 19:43:04.515: D/AsyncTaskExample(10299): Task = 8 Task Running in Background
08-02 19:43:**04.515**: D/AsyncTaskExample(10299): Task = 7 Task Execution Completed


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow