Es gibt verwandte Fragen, z. B. Wie kann ich zwei Parameter an eine AsyncTask-Klasse übergeben? Aber ich hatte die Schwierigkeit, vergeblich zu versuchen, mehrere Grundelemente als Parameter an eine AsyncTask zu übergeben, und möchte daher mitteilen, was ich entdeckt habe. Diese Subtilität wird in den vorhandenen Fragen und Antworten nicht erfasst, daher möchte ich jedem helfen, der auf dasselbe Problem stößt wie ich, und ihm den Schmerz ersparen.
Die Frage ist folgende: Ich habe mehrere primitive Parameter (z. B. zwei Longs), die ich an eine AsyncTask übergeben möchte, um sie im Hintergrund auszuführen. Wie kann das gemacht werden? (Meine Antwort ... nachdem ich eine Weile damit zu kämpfen hatte ... ist unten zu finden.)
android
android-asynctask
primitive
variadic-functions
Robguinness
quelle
quelle
Antworten:
Wickeln Sie einfach Ihre Grundelemente in einen einfachen Container und übergeben Sie diesen als Parameter an
AsyncTask
:Nennen Sie es so:
quelle
Ein anderer Weg: Sie müssen lediglich den MyTask-Konstruktor in Ihre MyTask-Klasse einfügen:
Dann ruf an
Ein zweiter Weg wie David Wassers Antwort.
quelle
<(String,Object,int),Void,Void>
Es ist (genau genommen) NICHT möglich, mehrere Grundelemente an AsyncTask zu übergeben. Wenn Sie beispielsweise die entsprechende Methode ausführen
myTask.execute(long1, long2)
und versuchen möchten, sie einzurichtenprivate class myTask extends AsyncTask<long, Void, Void>
:Ihre IDE wird sich wahrscheinlich darüber beschweren, dass eine Supertyp-Methode überschrieben werden muss. Beachten Sie, dass Sie das so genannte verwenden varargs Methodensignatur für
doInBackground
, wo(long... params)
wie wenn man sagt : „Ich eine variable Anzahl von Long - Positionen akzeptieren ist, gespeichert als ein Array mit Namen params. Ich verstehe nicht ganz , was bewirkt , dass ein Compiler / IDE Beschwerde angehoben werden , aber ich denke, es hat damit zu tun, wie die generische KlasseParams
definiert ist.In jedem Fall ist es möglich, problemlos das zu erreichen, was Sie wollen, vorausgesetzt, Sie wandeln Ihre Grundelemente korrekt in ihre jeweiligen nicht-primitiven Wrapper um (z. B. int => Integer, long => Long usw.). Tatsächlich müssen Sie Ihre Grundelemente nicht explizit in Nicht-Grundelemente umwandeln. Java scheint das für Sie zu erledigen. Sie müssen Ihre ASyncTask nur wie folgt einrichten (zum Beispiel für Longs):
Sie können diese Klasse dann wie ursprünglich beabsichtigt verwenden, z.
Oder für eine beliebige Anzahl von Grundelementen, die Sie möchten, vorausgesetzt, sie sind vom gleichen Typ. Wenn Sie mehrere Arten von Grundelementen übergeben müssen, ist dies ebenfalls möglich. Sie müssen jedoch Folgendes ändern:
Dies ist flexibler, erfordert jedoch das explizite Umwandeln der Parameter in ihre jeweiligen Typen. Wenn diese Flexibilität nicht benötigt wird (dh ein einzelner Datentyp), empfehle ich, bei der ersten Option zu bleiben, da diese etwas besser lesbar ist.
quelle
protected LocationItemizedOverlay doInBackground(Object[] objects)
auch Folgendes verwenden und für die Definition der asynchronen Aufgabe Folgendes hinzufügen.private class MyTask extends AsyncTask<Object, Void, Void>
Die integrierte Ausführungsmethode akzeptiert ein Array von Parametern , aber alle müssen vom definierten Typ sein. Wenn Sie also einfach den PARAM- Typ auf OBJECT setzen , können Sie alles übergeben , was Sie möchten , solange sie untergeordnete Objekte von Objekten sind. ...
Dann wandeln Sie in Ihrem doInBackGround einfach jeden Parameter um, um wieder das zu erreichen, was Sie brauchen:
Und Ihre Ausführung ist einfach:
Nicht so gut wie das Einwickeln in Ihre eigene Wrapper-Klasse oder ein Bundle oder Hash oder so, weil Sie von beiden Seiten in der Reihenfolge abhängig sind, aber es wird funktionieren. Natürlich können Sie Ihr Array einfach zu einem Parameter von HashMap (,) machen, und Sie implementieren zu diesem Zeitpunkt im Grunde genommen ein Bundle benutzerdefiniert, aber es wird funktionieren.
quelle
Ich mag Malajisis Methode, aber wenn Sie es nicht getan haben, könnten Sie dann nicht die Bundle-Klasse verwenden?
Dann übergeben Sie einfach das Bundle und packen es in MyTask aus. Ist das eine schreckliche Idee? Sie vermeiden das Erstellen einer benutzerdefinierten Klasse und es ist flexibel, wenn Sie später zusätzliche Parameter übergeben müssen.
Update: Es ist einige Jahre her, seit ich diese Antwort geschrieben habe, und ich mag sie jetzt wirklich nicht. Ich würde empfehlen, kein Bundle zu verwenden. Wenn Sie mehrere Parameter an eine Asynctask übergeben müssen (oder wirklich irgendetwas), verwenden Sie eine benutzerdefinierte Klasse, die alle Ihre Parameter gleichzeitig enthält. Die Verwendung eines Bundles ist eine gute Lösung für ein Problem, das Sie nicht haben sollten. Es gibt kein Gesetz gegen das Erstellen einer benutzerdefinierten Klasse, die genau das enthält, was Sie benötigen, und sonst nichts.
Warum verwenden Sie keine Coroutinen? Asynctasks sind so 2014.
quelle
Dies wird über Unterklassen gelöst. Google hat ein Beispiel zur Lösung dieses Problems (Unterklasse) in der offiziellen Android AsyncTask-Dokumentation:
http://developer.android.com/reference/android/os/AsyncTask.html
Beispiel:
quelle