在聯想 S9 等部分手機上,HTTP 通訊寫入數據後調用 out.flush(),線程永久阻塞,無異常拋出,初以為是撥號模塊故障。
flush() 觸發 HTTP 1.1 的 Chunked Transfer Encoding (分塊傳輸)。若服務器/代理為 HTTP 1.0 或不支持分塊傳輸,會導致連接掛起。
「調用 flush() 使用了 HTTP 1.1 的特性,允許分小塊發送數據。若使用 HTTP 1.0 服務器/代理,分塊傳輸會導致問題。」
close() 替代 flush()。close() 會發送 Content-Length 頭並一次性寫完,不使用分塊編碼。write() + close() 發送,避免中間 flush()。// 錯誤寫法 (可能阻塞)
OutputStream out = httpConn.openOutputStream();
out.write(requestData);
out.flush(); // 觸發分塊編碼,風險!
out.close();
// 正確寫法 1: 小數據直接 close
OutputStream out = httpConn.openOutputStream();
out.write(requestData);
out.close(); // 無分塊,安全
// 正確寫法 2: 大數據緩衝後一次性發送
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// ... 寫入大量數據到 baos ...
byte[] fullData = baos.toByteArray();
httpConn.setRequestProperty("Content-Length", String.valueOf(fullData.length));
OutputStream out = httpConn.openOutputStream();
out.write(fullData);
out.close();
flush() 在移動網絡環境下是高風險操作**。close() 結束寫入**。M-Mail 版本更新包含上述修復,建議所有用戶升級以避免 HTTP 通訊阻塞問題。