Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android webview通過http get下載文件下載兩次的問題及解決方法

Android webview通過http get下載文件下載兩次的問題及解決方法

編輯:關於Android編程

一、現象      一般通過Android webview進行下載文件的方法是      1.重寫DownloadListener的onDownloadStart方法,在onDownloadStart方法中彈出對話框提示用戶有新的文件需要下載      2.用戶點擊確定之後,通過http get下載文件      由於Android webview的實現,以上的下載文件步驟涉及到了兩次get的操作。第一次是用戶在webview中點擊下載鏈接時,webview自動發送http get請求,這個時候服務器除了將文件信息發送過來之外,會同時將文件的內容發送給webview。第二次是在步驟2,由自己設計的程序發起的。      為了驗證如上結論,我在Android 4.4系統中的自帶浏覽器通過訪問並下載這個測試鏈接,並用wireshark進行抓包查看結果。通過如下三張圖,我覺得可以驗證同一份文件確實被傳了兩次。因為兩個不同http get請求之後都可以看到服務器向客戶端發送的連續的TCP數據包。               二、解決方法      針對這個問題,我覺得比較完美的解決辦法是webview在進行get的時候能夠緩存相應的文件內容,並且開放相應的接口給應用進行緩存的讀取。但是我並沒有發現相應的api。      於是便有了如下的解決辦法:在webview加載url之前,通過鏈接中的一些特定字段發現進行下載操作。然後通過http head請求獲取文件名和大小等相關信息。由於http head只是請求文件相關信息,所以服務器只是通過http response將文件信息返回而不通過tcp發送文件具體內容。   2.1 在繼承自WebViewClient的類的shouldOverrideUrlLoading方法中檢查鏈接類型,並通過http head獲取文件大小,名稱信息。在以下代碼基礎上需要增加合適的獲取文件名稱代碼和handler的代碼。     if (url.contains("可能會進行下載的鏈接字段")) {     new Thread() {         public void run() {             HttpHead httpGet = new HttpHead(mUrl);             boolean success = true;             String filename="";             Integer fileLength=100;                              try {                 HttpParams httpParameters = new BasicHttpParams();                 HttpConnectionParams.setConnectionTimeout(httpParameters, 8000);                 HttpConnectionParams.setSoTimeout(httpParameters, 8000);                 DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);<br>                 //需要的話可能得增加cookie<br>                 HttpResponse httpResponse = httpClient.execute(httpGet);                 if (httpResponse.getStatusLine().getStatusCode() == 200) {                                            //如果文件名保存在Content-Disposition中,並且用的是gb2312編碼方式可以參考這段代碼                     String nameString=httpResponse.getFirstHeader("Content-Disposition").getValue();                     char [] nameChar=new char[nameString.length()];                     byte [] nameBytes=new byte[nameString.length()];                     nameString.getChars(0, nameString.length(), nameChar, 0);                     for (int i = 0; i < nameChar.length; i++) {                         nameBytes[i]=(byte)nameChar[i];                     }                     filename=EncodingUtils.getString(nameBytes, "gb2312");                     Log.d(TAG, "file name is "+filename);                                           String contentLength=httpResponse.getFirstHeader("Content-Length").getValue();                     fileLength=Integer.parseInt(contentLength);                     success=true;                 }else {                     success=false;                 }             } catch (Exception e) {                 success = false;                 e.printStackTrace();             }                           Message msg = Message.obtain();             if(success) {                 msg.what = GET_FILE_INFO_FINISHED;                 Bundle mBundle=new Bundle();                 mBundle.putString("fileName", filename);                 mBundle.putInt("fileLength", fileLength);                 msg.setData(mBundle);             }             else {                 msg.what = GET_FILE_INFO_FAILED;             }             mHandler.sendMessage(msg);         }     }.start(); }else {     view.loadUrl(url); } 2.2 適用情況      在Android 4.4中,根據網頁的特點,可能會出現點擊下載鏈接,而shouldOverrideUrlLoading不被調用的情況,這時2.1中方法則失效了。不過對於4.4之前的系統應該是適用的。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved