Próbuję napisać prostą aplikację, która zostanie zaktualizowana. W tym celu potrzebuję prostej funkcji, która może pobrać plik i pokazać aktualny postęp w ProgressDialog
. Wiem, jak to zrobić ProgressDialog
, ale nie jestem pewien, jak wyświetlić bieżący postęp i jak pobrać plik.
java
android
download
android-asynctask
Tom Leese
źródło
źródło
Odpowiedzi:
Istnieje wiele sposobów pobierania plików. Poniżej zamieszczę najczęstsze sposoby; od Ciebie zależy, która metoda będzie lepsza dla Twojej aplikacji.
1. Użyj
AsyncTask
i pokaż postęp pobierania w oknie dialogowymTa metoda pozwoli Ci wykonać niektóre procesy w tle i jednocześnie zaktualizować interfejs użytkownika (w tym przypadku zaktualizujemy pasek postępu).
Import:
To jest przykładowy kod:
AsyncTask
Będzie wyglądać następująco:Metoda powyżej (
doInBackground
) działa zawsze w wątku w tle. Nie powinieneś tam wykonywać żadnych zadań interfejsu użytkownika. Z drugiej stronyonProgressUpdate
ionPreExecute
działają w wątku interfejsu użytkownika, dzięki czemu można zmienić pasek postępu:Aby to uruchomić, potrzebujesz uprawnienia WAKE_LOCK.
2. Pobierz z usługi
Najważniejsze pytanie brzmi: jak zaktualizować swoją aktywność w serwisie? . W następnym przykładzie użyjemy dwóch klas, o których możesz nie wiedzieć:
ResultReceiver
iIntentService
.ResultReceiver
to ten, który pozwoli nam zaktualizować nasz wątek z usługi;IntentService
jest podklasą, zService
której odradza się wątek do wykonywania zadań w tle (powinieneś wiedzieć, żeService
działa tak naprawdę w tym samym wątku Twojej aplikacji; po rozszerzeniuService
musisz ręcznie spawnować nowe wątki, aby uruchomić operacje blokowania procesora).Usługa pobierania może wyglądać następująco:
Dodaj usługę do swojego manifestu:
Aktywność będzie wyglądać następująco:
Oto
ResultReceiver
nadchodzi gra:2.1 Użyj biblioteki Groundy
Groundy to biblioteka, która zasadniczo pomaga uruchamiać fragmenty kodu w usłudze w tle i jest oparta na powyższej
ResultReceiver
koncepcji. Ta biblioteka jest obecnie nieaktualna . Tak wyglądałby cały kod:Aktywność, w której wyświetlasz okno dialogowe ...
GroundyTask
Realizacja wykorzystywane przez Groundy aby pobrać plik i pokazać postęp:I po prostu dodaj to do manifestu:
Myślę, że nie może być łatwiej. Wystarczy pobrać najnowszy słoik od Github i jesteś gotowy do pracy. Należy pamiętać, że głównym celem Groundy jest nawiązywanie połączeń z zewnętrznymi aplikacjami REST api w usłudze działającej w tle i łatwe publikowanie wyników w interfejsie użytkownika. Jeśli robisz coś takiego w swojej aplikacji, może to być bardzo przydatne.
2.2 Użyj https://github.com/koush/ion
3. Użyj
DownloadManager
klasy (GingerBread
i tylko nowsze)GingerBread wprowadził nową funkcję,
DownloadManager
która umożliwia łatwe pobieranie plików i delegowanie ciężkiej pracy związanej z obsługą wątków, strumieni itp. Do systemu.Najpierw zobaczmy metodę narzędzia:
Nazwa metody wyjaśnia wszystko. Gdy masz pewność, że
DownloadManager
jest dostępny, możesz zrobić coś takiego:Postęp pobierania będzie widoczny na pasku powiadomień.
Końcowe przemyślenia
Pierwsza i druga metoda to tylko wierzchołek góry lodowej. Jest wiele rzeczy, o których musisz pamiętać, jeśli chcesz, aby Twoja aplikacja była niezawodna. Oto krótka lista:
INTERNET
iWRITE_EXTERNAL_STORAGE
); takżeACCESS_NETWORK_STATE
jeśli chcesz sprawdzić dostępność Internetu.O ile nie potrzebujesz szczegółowej kontroli procesu pobierania, rozważ użycie
DownloadManager
(3), ponieważ obsługuje on już większość wyżej wymienionych elementów.Pamiętaj jednak, że Twoje potrzeby mogą się zmienić. Na przykład
DownloadManager
nie buforuje odpowiedzi . Ślepo pobierze ten sam duży plik wiele razy. Nie ma łatwy sposób, aby naprawić to po fakcie. Jeśli zaczniesz od podstawowegoHttpURLConnection
(1, 2), wystarczy dodaćHttpResponseCache
. Tak więc początkowy wysiłek nauki podstawowych, standardowych narzędzi może być dobrą inwestycją.źródło
close()
strumieni (input
ioutput
)finally
zamiasttry
, w przeciwnym razie, jeśli wcześniejclose()
zostanie zgłoszony wyjątek , wiszą niezamknięte strumienie.sdcard/
używaj kodu / użyciaEnvironment.getExternalStorageDirectory()
.Nie zapomnij dodać uprawnień do pliku manifestu, jeśli będziesz pobierać rzeczy z Internetu!
źródło
Tak powyższy kod będzie działać .Ale jeśli aktualizowania
progressbar
inonProgressUpdate
zAsynctask
i naciśnięciu przycisku Wstecz lub zakończyć swoją działalnośćAsyncTask
traci swój utwór z UI .i kiedy wrócisz do swojej działalności, nawet jeśli pobieranie jest uruchomiony w tle widać brak aktualizacji na pasku postępu. WięcOnResume()
spróbuj uruchomić wątek jakrunOnUIThread
w przypadku zadania licznika czasu, które aktualizuje twojeprogressbar
wartości aktualizując je zAsyncTask
działającego tła.Nie zapomnij zniszczyć wątku, gdy Twoja aktywność nie jest widoczna.
źródło
Polecam korzystanie z mojego projektu Netroid , jest oparty na Volley . Dodałem do niego pewne funkcje, takie jak wywołanie zwrotne wielu zdarzeń, zarządzanie pobieraniem plików. To może być pomocne.
źródło
SSLSocketFactory
dodawanie,HostnameVerifier
nie jest możliwe i potrzebuję takiego weryfikatora. Podniósł problem dotyczący tego.Zmodyfikowałem
AsyncTask
klasę, aby obsługiwać tworzenieprogressDialog
w tym samym kontekście. Myślę, że następujący kod będzie bardziej przydatny. (można go wywołać z dowolnego działania, wystarczy przekazać kontekst, plik docelowy, komunikat w oknie dialogowym)źródło
Nie zapomnij zastąpić „/ sdcard ...” nowym plikiem („/ mnt / sdcard / ...”), w przeciwnym razie otrzymasz wyjątek FileNotFoundException
źródło
Environment.getExternalStorageDirectory().getAbsolutePath()
uzyskania ścieżki do sdcard. Nie zapomnij również sprawdzić, czy pamięć zewnętrzna jest zamontowana -Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
( Mannaz )Uważam, że ten post na blogu jest bardzo pomocny. Korzysta z loopJ do pobierania pliku, ma tylko jedną prostą funkcję, będzie pomocny dla niektórych nowych facetów z Androidem.
źródło
Kiedy zacząłem uczyć się programowania na Androida, nauczyłem się, że
ProgressDialog
to jest właściwa droga. IstniejesetProgress
metoda,ProgressDialog
którą można wywołać, aby zaktualizować poziom postępu podczas pobierania pliku.Najlepsze, jakie widziałem w wielu aplikacjach, to to, że dostosowują atrybuty tego okna dialogowego postępu, aby uzyskać lepszy wygląd i działanie okna dialogowego postępu niż wersja standardowa. Dobrze jest utrzymać użytkownika zaangażowanego w animację żaby, słonia lub uroczych kotów / szczeniąt. Każda animacja w oknie dialogowym postępu przyciąga użytkowników i nie mają oni ochoty długo czekać.
źródło
Moja osobista rada to korzystanie z Dialogu Postępów i budowanie go przed wykonaniem lub inicjowanie w
OnPreExecute()
, publikowanie postępów często, jeśli używasz poziomego stylu paska postępu w oknie dialogowym postępu. Pozostała część to optymalizacja algorytmudoInBackground
.źródło
Skorzystaj z biblioteki zapytań na Androida, naprawdę bardzo fajnej. Możesz ją zmienić tak, aby używała,
ProgressDialog
jak widać na innych przykładach, ta pokaże widok postępu z twojego układu i ukryje go po zakończeniu.źródło
Dodaję kolejną odpowiedź na inne rozwiązanie, którego używam teraz, ponieważ Android Query jest tak duży i nie wymaga konserwacji, aby zachować zdrowie. Więc przeniosłem się do tego https://github.com/amitshekhariitbhu/Fast-Android-Networking .
źródło
Uprawnienia
Korzystanie z HttpURLConnection
źródło
Postępy menedżera pobierania można obserwować za pomocą LiveData i coroutines, patrz streszczenie poniżej
https://gist.github.com/FhdAlotaibi/678eb1f4fa94475daf74ac491874fc0e
źródło
Ważny
AsyncTask jest przestarzały w Androidzie 11.
Aby uzyskać więcej informacji, sprawdź następujące posty
Prawdopodobnie powinien przejść do struktury zgodnej z zaleceniami Google
źródło
Do pobierania plików w Kotlin możemy użyć menedżera koroutin i pracy.
Dodaj zależność w build.gradle
Klasa WorkManager
Rozpocznij pobieranie za pośrednictwem menedżera pracy w klasie aktywności
źródło