Berechnungen aus MainActivity auslagern - AsyncTask wird bereits verwendet - Alternativen?

  • Antworten:4
superSharp
  • Forum-Beiträge: 89

24.12.2017, 09:43:15 via Website

Guten Morgen und schöne Weihnachten!

Ich möchte gerne eine Berechnung aus der MainActivity in einen extra Thread auslagern (dabei wird die UI nicht geupdated - ich möchte nur den Wert am Ende haben - und eine Callback Funktion oder dass ich mit bekomme wann der Thread fertig ist), ich benutze bereits einen AsyncTask der nach seiner Berechnung die UI updated.

Ich hab in einem Video gehört, dass alle AsyncTasks im selben Thread laufen, da es nun aber bei der Bedienung der App dazu kommen kann, dass bereits dieser AsyncTask aktiv ist, wollte ich mich nach einer Lösung umsehen, die einen weiteren Thread benutzt - was nimmt man da am Besten?

Ich möchte gerne so viele Kerne meines Smartphones benutzen wie möglich :D

— geändert am 24.12.2017, 09:43:55

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

24.12.2017, 12:46:49 via Website

Hallo superSharp,
Dass alle Tasks in einem Thread laufen ist nur die halbe Wahrheit.
Das stimmt nämlich, wenn du einen AsyncTask nur mit AsyncTask#execute(); startest.

Du kannst auch für jeden Task einen eigenen Thread machen (solange es der ThreadPool zulässt):

// parallel execution
AsyncTask aTask4 = new MyAsyncTask();
aTask4.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, [parameters]);

Das geht jedoch nur wenn du keine Uraltgeräte Version <= 3.x unerstützt. Ansonsten noch mit if unterscheiden:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)

LG Pascal //It's not a bug, it's a feature. :) ;)

superSharp

Antworten
superSharp
  • Forum-Beiträge: 89

24.12.2017, 14:05:28 via Website

Danke dir, ich hab das nun auch mal versucht. Meine Smartphone hat 4 Kerne und ich hab 4 AsyncTasks nacheinander gestartet, allerdings erreiche ich nur eine CPU-Auslastung von max. 72% (im Android Profiler) - wie kommt das? Die Berechnungsdauer ist bei allen Tasks ungefähr gleich und liegt bei 1 - 5s.

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

24.12.2017, 15:09:33 via App

Kommt immer darauf an was und wie du deine Berechnung machst. Ich vermute dass Android selten auf 100% geht.

LG Pascal //It's not a bug, it's a feature. :) ;)

superSharp

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

27.12.2017, 16:38:46 via Website

Pascal P.

Das geht jedoch nur wenn du keine Uraltgeräte Version <= 3.x unerstützt. Ansonsten noch mit if unterscheiden:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)

Kleine Ergänzung hierzu: Für solche Fälle gibt es eigentlich immer "Compat" Klassen, die diesen Version-Fork-Code einsparen. Meistens reicht es einfach an die Klasse, die man EIGENTLICH nutzen will, ein "Compat" anzuhängen.
Beim AsyncTask ist es halt AsyncTaskCompat.executeParallel(AsyncTask task, Params... params)

Das gleiche gibt es für hunderte andere Fälle ... MenuItemCompat, ResourcesCompat, usw. usf.
Siehe: https://blog.egorand.me/all-the-things-compat/

P.S. In diesem konkreten Fall ist die Klasse ab API 26 als deprecated markiert, aber das ganze mal so als genereller Tipp, um Wurst-Code zu sparen ;-)

— geändert am 27.12.2017, 16:45:40

Antworten