Android實現單線程非同步多檔案下載的代碼

來源:互聯網
上載者:User

 現在有一個需求,需要下載的檔案有很多個,放在一個開放連接埠(URL)的目錄下,這個目錄下的檔案會變動,就是檔案名稱不定。現在需要把這個目錄下的檔案下載到Android裝置上。我找了很多資料,發現不能把一個URL目錄下的全部檔案以檔案名稱的方式列出來(?)。那麼,把需要下載的多個檔案打包成一個.zip檔案放到URL上,下載下來後再通過代碼解壓,解壓時如果有中文名的檔案,不能正常解壓(這個在另一篇文章中記載)。走另一條道路:需要下載的檔案關聯到一個點菜系統的菜單的全部圖片,檔案名稱就是菜單的圖片名。點菜系統的菜單可以從伺服器的資料庫中查詢到。這樣就把菜單全部遍曆一遍,每個菜單的圖片名(如果有的話)和URL目錄拼成檔案下載路徑(經理提出的方法),使用迴圈遍曆下載。

/**  * 準備下載菜譜圖片,檢查SDcard是否可用,設定下載更新地址,下載後儲存位置資訊。  */ private void downloadMenuImageCheck() {  String status = Environment.getExternalStorageState();  if (!Environment.MEDIA_MOUNTED.equals(status)) {   ToastUtils.showFailure(getApplicationContext(),     "SDcard cannot use!");   return;  }  RequestFileInfo requestFileInfo = new RequestFileInfo();  requestFileInfo.fileParentUrl = "http://192.168.1.103:8181/menupic";  requestFileInfo.saveFilePath = Environment    .getExternalStorageDirectory().getAbsolutePath()    + "/waitab/menupic";  showDialog(DialogUtil.DIALOG_DOWNLAOD_IMAGE_PROGRESS);     new DownlaodUpdateTask().execute(requestFileInfo); } /**  * 找出所有菜品資料  * @return List<menux>  */ private List<menux> updateMenux() {  return mdb.findAll(); } /**  * 找出所有菜品資料  * 下載菜品圖片類   * 遍曆菜品資料List,根據每一個菜品圖片名字拼出下載路徑  * 多檔案迴圈遍曆單線程下載  *   * @author modify by ZX  *   */ private class DownlaodUpdateTask extends   AsyncTask<requestfileinfo progressvalue="" basiccallresult=""> {  @Override  protected BasicCallResult doInBackground(RequestFileInfo... params) {   Log.d(TAG, "start doInBackground!");    final RequestFileInfo req = params[0];   ProgressValue progressValue = new ProgressValue(0, getString(R.string.msg_fetching_menu));   publishProgress(progressValue);      List<menux> menuxs ;   menuxs = updateMenux();   if (menuxs == null) {    dismissDialog(DialogUtil.DIALOG_DOWNLAOD_IMAGE_PROGRESS);     return new BasicCallResult(      "Can not get menu data! ", false);    }      // 根據檔案路徑建立目錄   File basePath = new File(req.saveFilePath);   if (!basePath.exists())    basePath.mkdirs();     int needDownloadImageCount = 0;//記錄需要下載的圖片數   int finishDownloadImageCount = 0;//記錄完成下載的圖片數   long startTime;   long endTime;   int length = 0;   double totalLength = 0;   int count = 0;      class ImageInfo{    public String imageName;    public String imageMenuTypeGroupx;    public HttpURLConnection conn;   }   List<imageinfo> imageInfos = new ArrayList<imageinfo>();      //遍曆菜品,取得需要下載的圖片檔案的總數量和能串連上的圖片檔案的總大小和資訊   for (Menux menux : menuxs) {    try {     String imageName = menux.getPicname();// 菜品圖片名     if (StringUtils.isNotEmpty(imageName)) {      needDownloadImageCount += 1;      URL url = new URL(req.fileParentUrl+ File.separator            + java.net.URLEncoder.encode(imageName,            "UTF-8")); // 如果菜品名是中文,為瞭解決亂碼問題,改變編碼方式      HttpURLConnection conn = (HttpURLConnection) url        .openConnection();// throws IOException      Log.i(TAG, "response code:" + conn.getResponseCode());      if (HttpURLConnection.HTTP_OK == conn.getResponseCode()) {       length += conn.getContentLength();       String imageMenuTypeGroupx = menux.getMenutype() + menux.getGroupx();// 菜品分類              ImageInfo imageInfo = new ImageInfo();       imageInfo.imageName = imageName;       imageInfo.imageMenuTypeGroupx = imageMenuTypeGroupx;       imageInfo.conn = conn;       imageInfos.add(imageInfo);      }     }    }catch(IOException e){     e.printStackTrace();    }   }      if(imageInfos.size() == 0){    return new BasicCallResult("No image need download! ", false);   }   totalLength = StringUtils.bytes2M(length);   progressValue = new ProgressValue(0, getString(R.string.msg_start_download_menuimage));   publishProgress(progressValue);       startTime = System.currentTimeMillis();      // 遍曆能夠串連上的圖片資訊下載   for (ImageInfo imageInfo : imageInfos) {    try {     /*     String imageName = menux.getPicname();// 菜品圖片名     if (StringUtils.isNotEmpty(imageName)) {       String imageMenuTypeGroupx = menux.getMenutype()        + menux.getGroupx();// 菜品分類      URL url = new URL(req.fileParentUrl+ File.separator            + java.net.URLEncoder.encode(imageName,            "UTF-8")); // 如果菜品名是中文,為瞭解決亂碼問題,改變編碼方式      HttpURLConnection conn = (HttpURLConnection) url        .openConnection();// throws IOException      Log.i(TAG, "response code:" + conn.getResponseCode());      if (HttpURLConnection.HTTP_OK == conn.getResponseCode()) {      */     String imageMenuTypeGroupx = imageInfo.imageMenuTypeGroupx;     String imageName = imageInfo.imageName;     InputStream is = imageInfo.conn.getInputStream();              /*        * 用這幾種方式開啟 is 都可以,用上面一種方式測試是否串連上,若串連上了,再做下載處理        *        InputStream is = conn.getURL().openStream();       InputStream is = url.openStream();                            */              // 根據菜品分類建立下一級目錄       File path;       if (StringUtils.isNotEmpty(imageMenuTypeGroupx)) {        path = new File(req.saveFilePath          + File.separator + imageMenuTypeGroupx);        if (!path.exists())         path.mkdir();       } else {        path = new File(req.saveFilePath);       }       File imageFile = new File(path, imageName);       FileOutputStream fos = new FileOutputStream(         imageFile);       //progressValue = new ProgressValue(0, " downloading:");       byte buffer[] = new byte[1024];       Log.d(TAG, "preper buffer!");       finishDownloadImageCount += 1;       do {        int numread = is.read(buffer);            if (numread <= 0) {         // publish end         break;        }        count += numread;        fos.write(buffer, 0, numread);        Log.d(TAG, "start fos.write!");                  endTime = System.currentTimeMillis();        double currentLength = StringUtils.bytes2M(count);         double kbPerSecond = count * 1f / (endTime - startTime);//即時下載速度因精確到毫秒級的時間,                                                                      //時間單位太大,會出現 endTime - startTime = 0 的情況,使得                                                                      // kbPerSecond無限大,改為計算平均下載速度。完整運算式應為                                                                      //(count / 1000f) / ((endTime - startTime) / 1000f),                                                                      // b/ms = Kb/S   (b=byte)           double downloadTotalTime = (endTime - startTime) / 1000f;        progressValue.message = String.format(          "%d/%d\t\t%.2f M/%.2f M\t\t%.2fKb/S\t\t\t%.1f S ", finishDownloadImageCount, needDownloadImageCount,          currentLength, totalLength, kbPerSecond, downloadTotalTime);        progressValue.progress = (int) ((((float) count) / length) * DialogUtil.LONG_PROGRESS_MAX);        publishProgress(progressValue);         } while (true);       fos.flush();       fos.close();       is.close();      //}     } catch (MalformedURLException e) {     e.printStackTrace();     return new BasicCallResult("Wrong url! ", false);      } catch (IOException e) {     // TODO Auto-generated catch block     e.printStackTrace();     return new BasicCallResult("Error: "       + e.getLocalizedMessage(), false);    }   }   BasicCallResult callResult = new BasicCallResult(     "download finish!", true);   callResult.data = needDownloadImageCount + "";//int轉String   callResult.data2 = String.valueOf(finishDownloadImageCount);   return callResult;  }  @Override  protected void onPostExecute(BasicCallResult result) {   if (result.ok) {    Log.d(TAG, "download menu image success!");     mProgressDialog.setMessage(getString(R.string.msg_download_image_success));    //ToastUtils.showSuccess(getApplicationContext(), "congratulation!  download success!");    if(Integer.parseInt(result.data) > Integer.parseInt(result.data2)){     ToastUtils.showLong(getApplicationContext(),"needDownload:" + result.data + "   "       + "finishDownload:" + result.data2 + "   "       + "you should put all menu images to server");    }    } else {    Log.d(TAG, "download menu image failed!");    ToastUtils.showFailure(getApplicationContext(), "5"      + result.message);   }      DiSettings.putBoolean(getApplicationContext(),     DiSettings.KEY_DOWNLOAD_MENU_IMAGE, false);      dismissDialog(DialogUtil.DIALOG_DOWNLAOD_IMAGE_PROGRESS);  }    @Override  protected void onProgressUpdate(ProgressValue... values) {               Log.d(TAG,values[0].toString());               mProgressDialog.setProgress(values[0].progress);               mProgressDialog.setMessage(values[0].message);       }    }</imageinfo></imageinfo></menux></requestfileinfo></menux></menux>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.