Tworzę aplikację, w której muszę aktualizować jakieś informacje za każdym razem, gdy użytkownik loguje się do systemu, korzystam również z bazy danych w telefonie. Do wszystkich tych operacji (aktualizacje, pobieranie danych z bazy danych itp.) Używam zadań asynchronicznych. Do tej pory nie widziałem, dlaczego nie powinienem ich używać, ale ostatnio doświadczyłem, że jeśli wykonam jakieś operacje, niektóre z moich zadań asynchronicznych po prostu zatrzymują się przed wykonaniem i nie skaczą do doInBackground. To było zbyt dziwne, żeby tak to zostawić, więc opracowałem kolejną prostą aplikację, aby sprawdzić, co jest nie tak. Co dziwne, zachowuję się tak samo, gdy liczba wszystkich zadań asynchronicznych osiąga 5, a szósta zatrzymuje się przed wykonaniem.
Czy Android ma limit asyncTasks w aktywności / aplikacji? A może to tylko jakiś błąd i należy go zgłosić? Czy ktoś napotkał ten sam problem i może znalazł sposób obejścia tego problemu?
Oto kod:
Po prostu utwórz 5 z tych wątków, aby pracować w tle:
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");
}
}
A potem utwórz ten wątek. Wejdzie do preExecute i zawiesi się (nie przejdzie do wykonania InBackground).
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");
}
}
źródło
core pool size
lubmaximum pool size
?@antonyt ma właściwą odpowiedź, ale jeśli szukasz prostego rozwiązania, możesz sprawdzić Needle.
Dzięki niemu możesz zdefiniować niestandardowy rozmiar puli wątków i, w przeciwieństwie do
AsyncTask
tego, działa na wszystkich wersjach Androida tak samo. Dzięki niemu możesz powiedzieć takie rzeczy jak:lub takie rzeczy
Potrafi o wiele więcej. Sprawdź to na GitHub .
źródło
Aktualizacja : od API 19 rozmiar puli wątków rdzenia został zmieniony, aby odzwierciedlić liczbę procesorów w urządzeniu, z minimum 2 i maksymalnie 4 na starcie, przy jednoczesnym wzroście do maksymalnego CPU * 2 +1 - odniesienie
Należy również zauważyć, że chociaż domyślny moduł wykonawczy AsyncTask jest seryjny (wykonuje jedno zadanie na raz iw kolejności, w jakiej przychodzi), z metodą
możesz zapewnić wykonawcę do wykonywania zadań. Możesz dostarczyć THREAD_POOL_EXECUTORowi wykonawcę pod maską, ale bez serializacji zadań, lub możesz nawet stworzyć swój własny Executor i dostarczyć go tutaj. Jednak uważnie zwróć uwagę na ostrzeżenie w Javadocach.
Jeszcze jedną rzeczą, na którą należy zwrócić uwagę, jest to, że zarówno platforma wykonawcza dostarczona przez środowisko wykonawcze THREAD_POOL_EXECUTOR, jak i jej wersja szeregowa SERIAL_EXECUTOR (która jest domyślna dla AsyncTask) są statyczne (konstrukcje na poziomie klasy), a zatem współdzielone przez wszystkie wystąpienia AsyncTask (s) w procesie aplikacji.
źródło