[問題]下載多個檔案使用ProgressDialog問題

看板AndroidDev作者 (阿東)時間6年前 (2018/08/21 08:09), 6年前編輯推噓5(504)
留言9則, 4人參與, 6年前最新討論串1/1
各位版友好, 最近在寫透過ProgressDialog依序顯示多個URL下載檔案的APP時有個問題 一直不知道該怎麼解,程式碼及敘述如下... 將多個url存入一個array list中,依序將這些url丟入function中可透過Progress Dialo g 讓使用者可以看到每個檔案的下載進度,每個檔案下載完後,Progress Dialog關閉, 等到下一個url被傳入downloadFile(url)時,再開啟一個Progress Dialog顯示進度條, 但目前只有第一筆url會正常顯示進度條,第二筆url的進度條一直停留在0%,但事實上 檔案有被下載到目的地中...請問是否哪裡寫錯了呢? in Main: for(String url:urls) { downloadFile(url); } downloadFile() function: private void download(String data) { app_name=data .substring(data.indexOf("0%2F"),data.indexOf("apk")) .replace("0%2F","") .replace(".",".apk"); final DownloadTask downloadTask = new DownloadTask(MainActivity.this); downloadTask.execute(data); mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { downloadTask.cancel(true); } }); } private class DownloadTask extends AsyncTask<String, Integer, String> { private Context context; private PowerManager.WakeLock mWakeLock; public DownloadTask(Context context) { this.context = context; } @Override protected String doInBackground(String... sUrl) { InputStream input = null; OutputStream output = null; HttpURLConnection connection = null; try { URL url = new URL(sUrl[0]); Log.i("Eden","surl:"+sUrl[0]); app_name=sUrl[0] .substring(sUrl[0].indexOf("0%2F"),sUrl[0].indexOf("apk") ) .replace("0%2F","") .replace(".",".apk"); connection = (HttpURLConnection) url.openConnection(); connection.connect(); if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { return "Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage(); } int fileLength = connection.getContentLength(); // download the file input = connection.getInputStream(); output = new FileOutputStream("/storage/emulated/0/Download/" +app_name); byte data[] = new byte[4096]; long total = 0; int count; while ((count = input.read(data)) != -1) { if (isCancelled()) { input.close(); return null; } total += count; if (fileLength > 0) publishProgress((int) (total * 100 / fileLength)); output.write(data, 0, count); } } catch (Exception e) { return e.toString(); } finally { try { if (output != null) output.close(); if (input != null) input.close(); } catch (IOException ignored) { } if (connection != null) connection.disconnect(); } return null; } @Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog = new ProgressDialog(MainActivity.this); mProgressDialog.setTitle("Downloading..."); mProgressDialog.setMessage("Downloading "+app_name); mProgressDialog.setIndeterminate(false); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setCancelable(true); mProgressDialog.setMax(100); PowerManager pm = (PowerManager) context .getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName()); mWakeLock.acquire(); mProgressDialog.show(); } @Override protected void onProgressUpdate(Integer... progress) { super.onProgressUpdate(progress); // if we get here, length is known, now set indeterminate to false mProgressDialog.setProgress(progress[0]); } @Override protected void onPostExecute(String result) { mWakeLock.release(); mProgressDialog.dismiss(); if (result != null) Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show(); else Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show(); } } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.227.181.38 ※ 文章網址: https://www.ptt.cc/bbs/AndroidDev/M.1534810195.A.020.html

08/21 22:10, 6年前 , 1F
異步執行你有了解運作原理嗎
08/21 22:10, 1F

08/21 22:11, 6年前 , 2F
看起來你在主程式的for一次就把所有下載同時進行
08/21 22:11, 2F
是的,程式運作是非同步所以第二個ProgressDialog彈出來後它就收不到download task 的 資料,因為第2個檔案已經下載完了...我想請問是否有方法能夠達成我要的效果呢? ※ 編輯: Dong0129 (36.227.181.38), 08/21/2018 23:19:33

08/22 01:19, 6年前 , 3F
你要在第一個異步執行完成後在進行第二個下載
08/22 01:19, 3F

08/22 01:24, 6年前 , 4F
建立一個變數downloadCount
08/22 01:24, 4F

08/22 01:24, 6年前 , 5F
記住目前下載到哪 在onPostExecute中 downloadCount++;
08/22 01:24, 5F

08/22 01:24, 6年前 , 6F
dowbliadFile(urls [downloadCount]);
08/22 01:24, 6F
已成功,原來一開始想的方向就錯了,謝謝!

08/22 22:08, 6年前 , 7F
只開一個thread跑所有download,用Handler 傳遞message
08/22 22:08, 7F
哈,這是另一種寫法,是抓download id去算檔案下載進度吧! 這兩種寫法的差異在哪呢?

08/22 22:49, 6年前 , 8F
把urls直接傳到asynctask裡面再用迴圈依次下載不好嗎
08/22 22:49, 8F
也是可行,一開始我想到的方向有點偏了,謝謝 ※ 編輯: Dong0129 (114.137.240.236), 08/23/2018 09:35:02

09/01 16:04, 6年前 , 9F
建議用rxJava 會比較容易處理這種資料流的event
09/01 16:04, 9F
文章代碼(AID): #1RUrXJ0W (AndroidDev)
文章代碼(AID): #1RUrXJ0W (AndroidDev)