2013-02-21 95 views
2

我有什麼感覺應該是一個解決的問題。我正在寫的Android應用程序發送的消息非常類似於用戶可以附加文件的SMS。我使用HttpUrlConnection發送這個數據到我的服務器,基本上歸結爲一個java.io.OutputStream(我把它包裝在一個DataOutputStream中)。真的顯示java輸出流的進度和超時

在移動設備上,有時網絡連接可能會非常糟糕,發送可能會花費太長時間。我有以下兩個基本問題:

  1. 用戶無法知道上傳
  2. 進度的方式,如果網絡是可怕的和進步糟糕 - 我寧願只是中止或有一些合理的超時而比坐在那裏嘗試5-10分鐘。

問題1:

我試圖根據我的OutputStream寫入顯示上傳進度()調用,我與4K緩衝區做:

 buffer = new byte[4096]; 
     long totalBytes = 0; 
     while ((bytesRead = fis.read(buffer)) > -1) { 
      totalBytes += bytesRead; 
      dos.write(buffer, 0, bytesRead); 
      if(showProgress){ 
       updateProgressBar(totalBytes); 
      } 
     } 

雖然這顯示了我的進步,它似乎只是顯示了應用程序可以將文件緩衝區傳輸到OS網絡堆棧緩衝區的速度。即使在慢速網絡上,進度條也可以很快完成,然後在我終於從我的服務器獲取JSON後告訴我發送狀態,然後再坐在那裏很長時間。當我將服務器傳遞給操作系統時,我的服務器告訴我它已收到它,當然有一些方法可以取得一些進展?

問題2:

有時網絡連接是壞的,但沒有足夠的硬件無線電觸發器沒有找到連接(在這種情況下,我進入了離線模式)回調壞。所以,當它不好,但不是我的應用程序將只是坐在那裏發送對話框,直到奶牛回家。這是連接到問題1,因爲我需要以某種方式知道實際的吞吐量,因爲OutputStream本身不提供超時機制。如果它低於某個門檻,我可以取消連接,並通知用戶他們需要得到合適的接待處。

側面說明:異步發送/輸出隊列是不是一種選擇,對我來說,因爲我不能堅持一個消息到磁盤,因此不能保證起草的消息是無限期它不能在稍後的時間點發送的情況。我需要/想要阻止發送,我只需要更聰明地放棄和/或通知用戶發生了什麼。

回答

1

它似乎只是顯示了應用程序可以將文件緩衝區傳輸到OS網絡堆棧緩衝區的速度。

這比這更糟糕。它顯示了應用程序可以將數據傳輸到HttpURLConnection的內部ByteArrayOutputStream的速度有多快,因此它可以在寫入任何內容之前查看內容長度並設置標題。

幸運的是,它比。如果您事先知道數據有多長,請設置固定長度傳輸模式。如果您不這樣做,請使用像1024這樣的低塊大小來設置分塊傳輸模式。

你會然後看你的應用程序可以多快地將數據移入套接字發送緩衝區;在分塊傳輸模式的情況下,以塊大小爲單位。但是,一旦套接字發送緩衝區填滿,您的寫入將會阻塞,您將看到實際的網絡傳輸,至少在您完成最後一次寫入之前。從這一點開始,寫入和關閉都是異步的,所以你的顯示器會早一點彈出,但每個人都有這個問題。

重新解決問題2,一旦轉移達到上述網絡速度,您就可以計算自己的吞吐量,並在相應情況下做出相應反應。