Android AsyncTask beschränkt Grenzen?

Ich entwickle eine Anwendung, wo ich einige Informationen aktualisieren muss jedes Mal, wenn Benutzer sich beim System anmeldet, verwende ich auch die Datenbank im Telefon. Für all jene Operationen (Updates, Abrufen von Daten von db und etc.) verwende ich asynchische Aufgaben. Bis jetzt habe ich nicht gesehen, warum ich sie nicht benutzen sollte, aber vor kurzem habe ich das erlebt, wenn ich einige Operationen mache einige meiner asynchronen Aufgaben einfach auf vor der Ausführung aufhören und nicht zu doInBackground springen. Das war einfach zu seltsam, um es so zu lassen, also habe ich eine andere einfache Anwendung entwickelt, um zu überprüfen, was falsch ist Und seltsam genug, bekomme ich das gleiche Verhalten, wenn die Anzahl der gesamten asynchronen Aufgaben erreichen 5, die 6. eine stoppt bei Pre-Execute.

Hat android eine Grenze von asyncTasks auf Aktivität / App? Oder ist es nur ein Bug und es sollte gemeldet werden? Hat jemand das gleiche Problem erlebt und vielleicht einen Workaround gefunden?

  • Lautstärke ändern Listener: Ist registerMediaButtonEventReceiver vorzuziehen auf onKeyDown?
  • Android: Authentifizierung mit NXP MiFare Ultralight C
  • Konnte keine Verbindung Fabrik Client
  • Android AsyncTask bleibt nach dem Abschluss in laufendem Zustand
  • Out of Memory Fehler in Android wegen Heap Größe zunehmend
  • Android, wie man Bild und Ort (mit Karte) im Gruppenchat mit xmpp-smack senden und empfangen kann
  • Hier ist der Code:

    Erstellen Sie einfach 5 dieser Threads, um im Hintergrund zu arbeiten:

    private class LongAsync extends AsyncTask<String, Void, String> { @Override protected void onPreExecute() { Log.d("TestBug","onPreExecute"); isRunning = true; } @Override protected String doInBackground(String... params) { Log.d("TestBug","doInBackground"); while (isRunning) { } return null; } @Override protected void onPostExecute(String result) { Log.d("TestBug","onPostExecute"); } } 

    Und dann schaffe diesen Thread. Es wird preExecute eingeben und hängen (es geht nicht zu doInBackground).

     private class TestBug extends AsyncTask<String, Void, String> { @Override protected void onPreExecute() { Log.d("TestBug","onPreExecute"); waiting = new ProgressDialog(TestActivity.this); waiting.setMessage("Loading data"); waiting.setIndeterminate(true); waiting.setCancelable(true); waiting.show(); } @Override protected String doInBackground(String... params) { Log.d("TestBug","doInBackground"); return null; } @Override protected void onPostExecute(String result) { waiting.cancel(); Log.d("TestBug","onPostExecute"); } } 

  • Erstellen einer Android Lock Screen App.
  • Typ Mismatch: kann nicht von StringBuilder in String konvertieren
  • Android Relative Layout alignCenter aus einer anderen Ansicht
  • Android: Wie man ein <string> -Element in ein anderes <string> -Element in XML einspritzt?
  • Gibt es eine Möglichkeit, Android ListView Animation zu deaktivieren?
  • Wie man android spinner popupBackground ändert
  • 3 Solutions collect form web for “Android AsyncTask beschränkt Grenzen?”

    Alle AsyncTasks werden intern von einem gemeinsamen (statischen) ThreadPoolExecutor und einem LinkedBlockingQueue gesteuert . Wenn Sie auf einer AsyncTask aufrufen, wird der ThreadPoolExecutor es ausführen, wenn es in der Zukunft bereit ist.

    Das ist, wann bin ich bereit? Das Verhalten eines ThreadPoolExecutor wird durch zwei Parameter, die ThreadPoolExecutor und die maximale ThreadPoolExecutor gesteuert. Wenn es weniger als Kern-Pool-Größe Threads aktuell aktiv und ein neuer Job kommt, wird der Executor einen neuen Thread erstellen und sofort ausführen. Wenn es mindestens Kernpool-Größen-Threads gibt, wird es versuchen, den Job zu warten und zu warten, bis ein Leerlauf-Thread verfügbar ist (dh bis ein anderer Job abgeschlossen ist). Wenn es nicht möglich ist, den Job in die Warteschlange zu stellen (die Warteschlange kann eine maximale Kapazität haben), wird es einen neuen Thread (bis zu den maximalen Poolgrößen-Threads) für die zu startenden Jobs erstellen. Nicht-Core-Leerlauf-Threads können schließlich entsprechend deaktiviert werden Ein Keep-Alive-Timeout-Parameter.

    Vor Android 1.6 war die Kernpoolgröße 1 und die maximale Poolgröße war 10. Seit Android 1.6 ist die Kernporengröße 5 und die maximale Poolgröße 128. Die Größe der Warteschlange ist in beiden Fällen 10. Das Keep-Alive-Timeout war 10 Sekunden vor 2.3 und 1 Sekunde seitdem.

    Bei all dem ist es nun klar, warum die AsyncTask nur 5/6 Ihrer Aufgaben ausführen wird. Die 6. Aufgabe wird in die Warteschlange gestellt, bis eine der anderen Aufgaben abgeschlossen ist. Dies ist ein sehr guter Grund, warum Sie AsyncTasks nicht für langlebige Operationen verwenden sollten – es wird verhindern, dass andere AsyncTasks immer ausgeführt werden.

    Für die Vollständigkeit, wenn Sie Ihre Übung mit mehr als 6 Aufgaben (z. B. 30) wiederholt haben, werden Sie sehen, dass mehr als 6 in doInBackground eintreten wird, doInBackground die Warteschlange voll wird und der Executor gedrückt wird, um mehr Worker-Threads zu erstellen. Wenn du mit der langwierigen Aufgabe aufbewahrt hast, solltest du sehen, dass 20/30 aktiv werden, mit 10 noch in der Warteschlange.

    @antonyt hat die richtige Antwort aber für den Fall, dass du nach einer einfachen Lösung suchst, dann kannst du Nadel ausprobieren.

    Mit ihm können Sie eine benutzerdefinierte Thread-Pool-Größe zu definieren, und im Gegensatz zu AsyncTask , funktioniert es auf alle Android-Versionen das gleiche. Mit ihm können Sie Dinge wie:

     Needle.onBackgroundThread().withThreadPoolSize(3).execute(new UiRelatedTask<Integer>() { @Override protected Integer doWork() { int result = 1+2; return result; } @Override protected void thenDoUiRelatedWork(Integer result) { mSomeTextView.setText("result: " + result); } }); 

    Oder Dinge wie

     Needle.onMainThread().execute(new Runnable() { @Override public void run() { // eg change one of the views } }); 

    Es kann noch viel mehr machen. Schau es dir bei GitHub an .

    Update : Seit API 19 wurde die Core-Thread-Pool-Größe geändert, um die Anzahl der CPUs auf dem Gerät zu widerspiegeln, mit einem Minimum von 2 und maximal 4 beim Start, während auf max. CPU * 2 +1 – Referenz

     // We want at least 2 threads and at most 4 threads in the core pool, // preferring to have 1 less than the CPU count to avoid saturating // the CPU with background work private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; 

    Beachten Sie auch, dass der Standard-Executor von AsyncTask seriell ist (führt eine Task zu einem Zeitpunkt und in der Reihenfolge, in der sie ankommen, mit der Methode aus

     public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) 

    Sie können einen Executor zur Ausführung Ihrer Aufgaben zur Verfügung stellen. Sie können die THREAD_POOL_EXECUTOR die unter der Haube Executor aber ohne Serialisierung von Aufgaben, oder Sie können sogar Ihre eigenen Executor und bieten sie hier. Beachten Sie jedoch sorgfältig die Warnung in den Javadocs.

    Warnung: Erlauben Sie, dass mehrere Aufgaben parallel von einem Thread-Pool laufen, ist in der Regel nicht das, was man will, weil die Reihenfolge ihrer Operation nicht definiert ist. Wenn zum Beispiel diese Aufgaben verwendet werden, um einen beliebigen Zustand gemeinsam zu ändern (z. B. das Schreiben einer Datei aufgrund eines Klicks), gibt es keine Garantien in der Reihenfolge der Änderungen. Ohne sorgfältige Arbeit ist es in seltenen Fällen möglich, dass die neuere Version der Daten von einem älteren Format überschrieben wird, was zu verdeckten Datenverlust- und Stabilitätsproblemen führt. Solche Änderungen werden am besten in Serie durchgeführt; Um zu garantieren, dass diese Arbeit unabhängig von der Plattformversion serialisiert wird, können Sie diese Funktion mit SERIAL_EXECUTOR nutzen.

    Eine weitere Sache zu beachten ist, dass sowohl das Framework zur Verfügung gestellt Executors THREAD_POOL_EXECUTOR und seine serielle Version SERIAL_EXECUTOR (die Standard für AsyncTask ist) sind statische (Klassen Ebene Konstrukte) und damit über alle Instanzen von AsyncTask (s) über Ihre App-Prozess freigegeben.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.