無線裝置支援的網路協定有限(HTTP、Socket、UDP),MIDP 1.0 強制實作 HTTP,其他為可選。為確保跨裝置移植性,首選 HTTP 協定,並可重用伺服器端 Web 程式碼。雖然 HTTP 為文字基礎、效率較低,但透過精心設計通訊內容、善用快取,仍可達到不錯速度。
application/octet-stream),配合 DataOutputStream 讀寫。採用 HttpThread 背景執行緒處理連線,搭配 HttpListener 介面實作觀察者模式,通知 UI 進度、完成、錯誤事件。
public interface HttpListener {
void onSetSize(int size);
void onFinish(byte[] data, int size);
void onProgress(int percent);
void onError(int code, String message);
}
繼承 Form,實作 HttpListener,顯示 Gauge 進度條與取消指令。
public void run() {
HttpConnection hc = null;
InputStream input = null;
try {
hc = (HttpConnection) Connector.open(url);
hc.setRequestMethod(HttpConnection.GET);
hc.setRequestProperty("User-Agent", USER_AGENT);
int code = hc.getResponseCode();
if (code != HttpConnection.HTTP_OK) {
listener.onError(code, hc.getResponseMessage());
return;
}
int size = (int) hc.getLength();
listener.onSetSize(size);
input = hc.openInputStream();
byte[] buffer = (size != -1) ? new byte[size] : new byte[MAX_LENGTH];
int index = 0, reads, percent = 0, tmp_percent = 0;
while (!cancel) {
int len = Math.min(128, buffer.length - index);
reads = input.read(buffer, index, len);
if (reads <= 0) break;
index += reads;
if (size > 0) {
tmp_percent = index * 100 / size;
if (tmp_percent != percent) {
percent = tmp_percent;
listener.onProgress(percent);
}
}
}
if (!cancel) {
if (size != -1 && index != size)
listener.onError(102, "Content-Length does not match.");
else
listener.onFinish(buffer, index);
}
} catch (IOException ioe) {
listener.onError(101, "IOException: " + ioe.getMessage());
} finally {
// 關閉資源
}
}
定義 DataHandler 介面,下一個畫面實作 setData(DataInputStream) 讀取資料。HttpWaitUI 在 onFinish 中將位元組陣列轉為 DataInputStream 傳遞給目標畫面並切換顯示。
Content-Type: application/x-www-form-urlencodedContent-LengthOutputStream 寫入 URL 編碼資料URLEncoder)Content-Type: multipart/form-data; boundary=XXX--boundary 分隔欄位,最後以 --boundary-- 結束\r\n 結束從回應標頭 Set-Cookie 擷取 Session ID(如 JSESSIONID),後續請求在標頭附加 Cookie: JSESSIONID=xxx。不建議使用 URL Rewriting,因 MIDP 難以解析。
採用觀察者模式分離網路邏輯與 UI,配合二進位協定、快取與進度控制,可建立高效、可移植的 J2ME 網路應用。