Ich habe diese zwei Klassen. Meine Hauptaktivität und die, die das erweitert AsyncTask
. Jetzt muss ich in meiner Hauptaktivität das Ergebnis aus dem OnPostExecute()
in der AsyncTask
. Wie kann ich das Ergebnis an meine Hauptaktivität weitergeben?
Hier sind die Beispielcodes.
Meine Haupttätigkeit.
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
Dies ist die AsyncTask-Klasse
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
android
android-asynctask
Stella
quelle
quelle
Antworten:
Einfach:
Erstellen Sie eine
interface
Klasse, wo diesString output
optional ist, oder können beliebige Variablen sein, die Sie zurückgeben möchten.Gehen Sie zu Ihrer
AsyncTask
Klasse und deklarieren Sie die SchnittstelleAsyncResponse
als Feld:In Ihrer Hauptaktivität müssen Sie eine
implements
Schnittstelle herstellenAsyncResponse
.AKTUALISIEREN
Ich wusste nicht, dass dies für viele von Ihnen so ein Favorit ist. Hier ist die einfache und bequeme Art der Verwendung
interface
.immer noch gleich
interface
. Zu Ihrer Information, Sie können dies in derAsyncTask
Klasse kombinieren .in der
AsyncTask
Klasse:Mach das in deiner
Activity
KlasseOder implementieren Sie die Schnittstelle in der Aktivität erneut
Wie Sie oben sehen können, müssen zwei Lösungen, die erste und die dritte, eine Methode erstellen
processFinish
. Die andere, die Methode, befindet sich im Aufruferparameter. Die dritte ist ordentlicher, weil es keine verschachtelte anonyme Klasse gibt. Hoffe das hilftTipp : Ändern Sie
String output
,String response
undString result
zu verschiedenen übereinstimmenden Typen, um unterschiedliche Objekte zu erhalten.quelle
Es gibt einige Optionen:
Verschachteln Sie die
AsyncTask
Klasse in IhrerActivity
Klasse. Angenommen, Sie verwenden nicht dieselbe Aufgabe in mehreren Aktivitäten, ist dies der einfachste Weg. Ihr gesamter Code bleibt gleich. Sie verschieben lediglich die vorhandene Aufgabenklasse in eine verschachtelte Klasse innerhalb der Klasse Ihrer Aktivität.Erstellen Sie einen benutzerdefinierten Konstruktor für Ihre
AsyncTask
, der auf Ihre verweistActivity
. Sie würden die Aufgabe mit so etwas instanziierennew MyAsyncTask(this).execute(param1, param2)
.quelle
static
? Verwenden Sie einfach einesfieldOrMethod
vonMyActivity
oderMyActivity.this.fieldOrMethod
wenn es im Schatten liegt.MyAsyncTask
ist keine innere Klasse.private
/protected
für Top-Level-Klassen ist nicht erlaubt, daher dachte ich, dass es eine nicht-static
innere Klasse sein muss.Ich fand den folgenden Ansatz sehr einfach.
Ich habe eine Schnittstelle für den Rückruf deklariert
Anschließend wurde eine asynchrone Aufgabe zum Beantworten aller Arten von parallelen Anforderungen erstellt
Rief dann die asynchrone Aufgabe auf, wenn auf eine Schaltfläche in der Aktivitätsklasse geklickt wurde.
Vielen Dank
quelle
Sie können diesen Code in Ihrer Hauptklasse ausprobieren. Das hat bei mir funktioniert, aber ich habe Methoden auf andere Weise implementiert
quelle
execute()
, siehe meine Antwort, ich habe dort einen Kommentar hinzugefügt. Vielleicht möchten Sie meine aktualisierte Antwort überprüfen. hoffe das hilft.Diese Antwort könnte spät sein, aber ich möchte einige Dinge erwähnen, wenn Sie davon
Activity
abhängig sindAsyncTask
. Dies würde Ihnen helfen, Abstürze und Speicherverwaltung zu verhindern. Wie bereits in den obigen Antworten erwähntinterface
, sagen wir auch Rückrufe. Sie werden als Informanten arbeiten, aber in diesen Fällen niemals starke Referenzen sendenActivity
oderinterface
immer schwache Referenzen verwenden.Im folgenden Screenshot erfahren Sie, wie dies zu Problemen führen kann.
Wie Sie sehen, wenn wir
AsyncTask
mit einer starken Referenz begonnen haben, gibt es keine Garantie dafür, dass unserActivity
/Fragment
am Leben bleibt, bis wir Daten erhalten.WeakReference
In diesen Fällen ist es daher besser, es zu verwenden, und dies hilft auch bei der Speicherverwaltung, da wir dies niemals tun werden die starke Referenz unsererActivity
dann wird es nach seiner Verzerrung zur Müllabfuhr berechtigt sein.Überprüfen Sie das folgende Code-Snippet, um herauszufinden, wie Sie fantastische WeakReference verwenden können -
MyTaskInformer.java
Schnittstelle, die als Informant arbeitet.MySmallAsyncTask.java
AsyncTask für eine lange laufende Aufgabe, die verwendet wirdWeakReference
.MainActivity.java
Diese Klasse wird verwendet, um meinAsyncTask
Implementierungsprogramminterface
für diese Klasse undoverride
diese obligatorische Methode zu starten .quelle
in Ihrem Oncreate ():
`
} `
quelle
Sie können dies in wenigen Zeilen tun. Überschreiben Sie einfach onPostExecute, wenn Sie Ihre AsyncTask aufrufen. Hier ist ein Beispiel für Sie:
Ich hoffe es hat dir geholfen, viel Spaß beim Codieren :)
quelle
onPostExecute
Methode.Warum machen es die Leute so schwer?
Dies sollte ausreichen.
Implementieren Sie onPostExecute nicht für die asynchrone Aufgabe, sondern für die Aktivität:
quelle
@Override
?Sie können die
get()
Methode vonAsyncTask
(oder die überladeneget(long, TimeUnit)
) aufrufen . Diese Methode wird blockiert, bis derAsyncTask
seine Arbeit abgeschlossen hat. An diesem Punkt erhalten Sie die zurückResult
.Es ist ratsam, zwischen dem Erstellen / Starten Ihrer asynchronen Aufgabe und dem Aufrufen der
get
Methode andere Arbeiten auszuführen , da Sie die asynchrone Aufgabe sonst nicht sehr effizient nutzen.quelle
Sie können Ihren eigenen Hörer schreiben. Es ist dasselbe wie bei HelmiB die Antwort von , sieht aber natürlicher aus:
Listener-Schnittstelle erstellen:
Dann schreiben Sie Ihre asynchrone Aufgabe:
Implementieren Sie den Listener schließlich in Aktivität:
Und so können Sie asyncTask aufrufen:
quelle
Hallo du kannst so etwas machen:
Erstellen Sie eine Klasse, die AsyncTask implementiert
In Hauptaktivität hinzufügen
quelle
Erstellen Sie ein statisches Element in Ihrer Aktivitätsklasse. Weisen Sie dann den Wert während der
onPostExecute
Wenn das Ergebnis Ihrer AsyncTask beispielsweise eine Zeichenfolge ist, erstellen Sie in Ihrer Aktivität eine öffentliche statische Zeichenfolge
public static String dataFromAsyncTask;
onPostExecute
Rufen Sie dann in der AsyncTask einfach einen statischen Aufruf Ihrer Hauptklasse auf und legen Sie den Wert fest.MainActivity.dataFromAsyncTask = "result blah";
quelle
Ich mache es mit Threading und Handler / Nachricht. Schritte wie folgt: Deklarieren Sie einen Fortschrittsdialog
Erstellen Sie eine Funktion zum Schließen des Dialogfelds, wenn der Vorgang abgeschlossen ist.
Codieren Sie Ihre Ausführungsdetails:
quelle
Sie müssen "Protokolle" verwenden , um Daten an die zu delegieren oder bereitzustellen
AsynTask
.Delegierte und Datenquellen
Ein Delegat ist ein Objekt, das im Namen oder in Abstimmung mit einem anderen Objekt handelt, wenn dieses Objekt auf ein Ereignis in einem Programm stößt. ( Apple Definition )
Protokolle sind Schnittstellen, die einige Methoden definieren, um bestimmte Verhaltensweisen zu delegieren.
Hier ist ein vollständiges Beispiel !!!
quelle
Versuche dies:
Und Anwendungsbeispiel:
quelle
Wahrscheinlich ein bisschen über Bord gehen, aber ich habe Rückrufe sowohl für den Ausführungscode als auch für die Ergebnisse bereitgestellt. Natürlich möchten Sie aus Gründen der Thread-Sicherheit vorsichtig sein, auf was Sie in Ihrem Ausführungsrückruf zugreifen.
Die AsyncTask-Implementierung:
Ein Rückruf:
Und schließlich die Ausführung der asynchronen Aufgabe:
quelle
Ich hoffe, Sie haben dies durchgemacht, wenn nicht, lesen Sie bitte.
https://developer.android.com/reference/android/os/AsyncTask
Abhängig von der Art der Ergebnisdaten sollten Sie die bestmögliche Option auswählen, die Sie sich vorstellen können.
Es ist eine gute Wahl, eine Schnittstelle zu verwenden
Einige andere Optionen wären ..
Wenn die AsyncTask-Klasse innerhalb der Klasse definiert ist, in der Sie das Ergebnis verwenden möchten. Verwenden Sie eine statische globale Variable oder get () , verwenden Sie sie von der äußeren Klasse ( ggf. flüchtige Variable ). Sie sollten jedoch über den Fortschritt von AsyncTask informiert sein oder zumindest sicherstellen, dass die Aufgabe abgeschlossen ist und das Ergebnis über die globale Variable / get () -Methode verfügbar ist. Sie können Polling, onProgressUpdate (Progress ...) , Synchronisation oder Schnittstellen verwenden (je nachdem , was für Sie am besten geeignet ist ).
Wenn das Ergebnis mit einem sharedPreference-Eintrag kompatibel ist oder als Datei im Speicher gespeichert werden kann , können Sie es sogar von der Hintergrundaufgabe selbst speichern und mithilfe der onPostExecute () -Methode
benachrichtigt werden, wenn das Ergebnis in verfügbar ist die Erinnerung.
Wenn die Zeichenfolge klein genug ist und zu Beginn einer Aktivität verwendet werden soll. Es ist möglich, Absichten ( putExtra () ) in onPostExecute () zu verwenden , aber denken Sie daran, dass statische Kontexte nicht so sicher sind .
Wenn möglich, können Sie eine statische Methode aus der onPostExecute () -Methode aufrufen, wobei das Ergebnis Ihr Parameter ist
quelle