Dateidownload auf Android: Von der Idee zum funktionierenden Code
\n\nJeder Android-Entwickler steht früher oder später vor der Aufgabe, eine Datei aus dem Netzwerk herunterzuladen. Dies kann ein App-Update, das Herunterladen eines Bildes, eines PDF-Dokuments oder eines Musiktitels sein. Aber die Datei einfach herunterzuladen ist nur die halbe Miete. Der Benutzer muss sehen, dass der Prozess läuft: wie viel heruntergeladen wurde, wie viel noch übrig ist und dass die App nicht eingefroren ist.
\n\nIn diesem Artikel analysieren wir eine klassische Frage von Stack Overflow, die tausende von Aufrufen erhalten hat: Wie lädt man eine Datei auf Android herunter und zeigt den Fortschritt in einem Dialogfenster an? Wir schreiben den Code in Java und verwenden AsyncTask und ProgressDialog (obwohl diese in modernen Projekten oft durch Coroutinen oder RxJava ersetzt werden, ist das Verständnis der Klassiker die Basis, die nirgendwo hingeht).
Bereit? Los geht's!
\n\nWarum ist es so schwierig? Drei Fallstricke beim Download in Android
\n\nAuf den ersten Blick scheint die Aufgabe einfach: Eine Verbindung öffnen, den Bytestrom lesen, in eine Datei schreiben. Aber in der Praxis stolpern Entwickler über drei Dinge:
\n\n- \n
- Der UI-Thread wird blockiert — Wenn der Download im Hauptthread gestartet wird, „friert“ die App ein und Android zeigt den Dialog „App antwortet nicht“ an. \n
- Der Fortschritt wird nicht aktualisiert — Selbst wenn Sie die Bytes zählen, können Sie die UI nicht einfach aus dem Hintergrundthread ändern. \n
- Die Konfiguration ändert sich — Der Benutzer dreht den Bildschirm und Ihre
Activitywird neu erstellt. Der Dialog verschwindet, während der Download ins Leere läuft. \n
Wir werden alle drei Probleme lösen. Beginnen wir mit der Architektur und schreiben dann den Code.
\n\nWerkzeuge auswählen: AsyncTask und ProgressDialog
\n\nFür Bildungszwecke verwenden wir den klassischen Ansatz:
\n- \n
AsyncTask— für die Ausführung von Hintergrundarbeit und die Veröffentlichung des Fortschritts. \n ProgressDialog— zur Anzeige der Prozentsätze. \n HttpURLConnection— für die HTTP-Anfrage (sie ist noch am Leben, wenn auch veraltet). \n
Wichtig: In realen Projekten werden heute häufiger DownloadManager, WorkManager oder Bibliotheken wie Retrofit + OkHttp verwendet. Aber zu verstehen, wie der Download „von Hand“ funktioniert, ist ein Must-have für jeden Entwickler.
Vollständiger Code: Dateidownload mit ProgressDialog
\n\nNachfolgend finden Sie eine fertige Klasse für den Download. Der Code ist auf Deutsch kommentiert, damit Sie sofort verstehen, was passiert.
\n\nimport android.app.ProgressDialog;\nimport android.content.Context;\nimport android.os.AsyncTask;\nimport android.os.Environment;\nimport android.widget.Toast;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\n\npublic class DownloadFileTask extends AsyncTask<String, Integer, String> {\n\n private Context context;\n private ProgressDialog progressDialog;\n\n public DownloadFileTask(Context context) {\n this.context = context;\n }\n\n @Override\n protected void onPreExecute() {\n super.onPreExecute();\n // Erstellen und Anzeigen des Fortschrittsdialogs\n progressDialog = new ProgressDialog(context);\n progressDialog.setTitle("Datei herunterladen");\n progressDialog.setMessage("Download läuft...");\n progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);\n progressDialog.setCancelable(false); // Versehentliches Schließen verhindern\n progressDialog.show();\n }\n\n @Override\n protected String doInBackground(String... params) {\n String fileUrl = params[0];\n String fileName = "downloaded_file.pdf"; // Kann als zweiter Parameter übergeben werden\n InputStream inputStream = null;\n FileOutputStream outputStream = null;\n\n try {\n // 1. Verbindung herstellen\n URL url = new URL(fileUrl);\n HttpURLConnection connec