Ich habe darüber gelesen AsyncTask
und 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>
android
android-asynctask
Fuchs
quelle
quelle
Antworten:
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()
undpostExecute()
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:
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.
quelle
onPostExecute(String result)
Methode zu übernehmen. Dies würde zukünftigen Lesern klarer machen, dass das Argument mit dem Rückgabewert von gefüllt istdoInBackground(String... params)
.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.
quelle
params
ist ein Array. (Im obigen Beispiel war es einString
Array.) Auf diese Weise können Sie mehrere Parameter desselben Typs übergeben. Dann können Sie diese Parameter zugreifen mitparams[0]
,params[1]
,params[2]
usw. In dem Beispiel gab es nur eine einzigeString
in demparams
Array. Wenn Sie mehrere Parameter unterschiedlichen Typs übergeben müssen (z. B. aString
und anint
), lesen Sie diese Frage .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.LongThread-Klasse (erweitert AsyncTask):
quelle
onPostExecute
in der Aktivität ist brillant.Ich habe ein einfaches Beispiel für die Verwendung von AsyncTask von Android erstellt. Es beginnt mit
onPreExecute(), doInBackground(), publishProgress()
und schließlichonProgressUpdate()
.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 SiepublishProgress
ausdoInBackground
dem rufenonProgressUpdate
Ihre UI - Widget zu aktualisieren.Nennen Sie es in Ihrer Aktivität so:
Entwicklerreferenz hier
quelle
Verschieben Sie diese beiden Zeilen:
aus der AsyncTask-
doInBackground
Methode und fügen Sie sie in dieonPostExecute
Methode ein. DuAsyncTask
solltest ungefähr so aussehen:quelle
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.Hintergrund / Theorie
Mit AsyncTask können Sie eine Aufgabe in einem Hintergrundthread ausführen und gleichzeitig Ergebnisse im UI-Thread veröffentlichen.
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.Diese drei Parameter entsprechen drei Hauptfunktionen, die Sie überschreiben können
AsyncTask
:doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
So führen Sie AsyncTask aus
execute()
mit Parametern, die an die Hintergrundaufgabe gesendet werden sollen.Was geschieht
Auf main / UI - Thread ,
onPreExecute()
wird aufgerufen.Auf einem Hintergrund - Thread ,
doInBackground(Params...)
wird aufgerufen.Params
wurden über übergebenexecute
.)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.onProgressUpdate()
zum Aufrufen.Im Hintergrund-Thread wird ein Ergebnis von zurückgegeben
doInBackground()
.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.
Die
doInBackground()
Methode lädt das Bild herunter und speichert es in einem Objekt vom Typ BitMap. DieonPostExecute()
Methode nimmt die Bitmap und platziert sie in der ImageView.Beispiel B.
Beispiel B Ausführung
quelle
Wenn eine asynchrone Aufgabe ausgeführt wird, durchläuft die Aufgabe vier Schritte:
Unten finden Sie ein Demo-Beispiel:
Und sobald Sie erstellt haben, wird eine Aufgabe ganz einfach ausgeführt:
quelle
Das kürzeste Beispiel dafür, wie man etwas asynchron macht:
Um es auszuführen:
quelle
Wie werden die in AsyncTask verwendeten Parameter gespeichert?
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
,Progress
undOutput
sind, 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ührtProgress
und gibt eineOutput
.Zum Beispiel:
Wie ist die Beziehung zu Methoden?
Wie schreibe ich das in den Code?
Wie werden Sie diese Aufgabe ausführen?
quelle
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:
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:
Dies wird Ihnen helfen, die Dinge besser zu kennen. Daher müssen Sie in Ihrem Fall Ihre Textansicht in der onPostExecute () -Methode festlegen.
quelle
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 ...
quelle
Beispiel für eine asynchrone Aufgabe mit POST-Anforderung:
quelle
Einfach:
quelle
Sie müssen die Schaltfläche onclicklistener deklarieren. Nach dem Klicken wird die AsyncTask-Klasse DownloadJson aufgerufen.
Der Prozess wird unten gezeigt:
quelle
quelle
Update: März 2020
Laut der offiziellen Dokumentation des Android-Entwicklers ist AsyncTask jetzt veraltet.
Es wird empfohlen, stattdessen Kotlin-Corourine zu verwenden. Sie können einfach asynchrone Aufgaben in einem sequentiellen Stil schreiben.
quelle
Beispiel für ein AsyncTask-Beispiel mit Fortschritt
quelle
ASync-Aufgabe;
quelle
MyTask
in KlasseMainActivity
? Ist das üblich?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:
Und so rufen Sie Ihre Aktivität oder Ihr Fragment auf:
quelle
Wenn Sie die AsyncTask-Klasse öffnen, sehen Sie den folgenden Code.
AsyncTask-Funktionen
Beispiel
quelle
Ändern Sie Ihren Code wie folgt:
quelle