初學 J2ME 網路開發時,常會直接在事件處理器中呼叫阻塞性網路 API,導致介面凍結。本文深入解析多執行緒架構原理,並示範如何實作高效、使用者友善的網路應用程式。
MIDP 執行環境中,startApp() 執行的主執行緒負責處理 UI 事件與畫面重繪。若在主執行緒執行耗時的網路操作(如 Connector.open()、InputStream.read()),整個應用程式會停止回應,使用者無法操作,甚至被系統判定為當機。

在命令處理中啟動新執行緒:
public void commandAction(Command c, Displayable d) {
if (c == connectCommand) {
new Thread() {
public void run() {
connect(); // 網路操作
}
}.start();
}
}

頻繁建立銷毀執行緒效率低落。更佳做法是啟動長期執行的工作執行緒,透過 wait()/notify() 待命喚醒:
class NetworkThread extends Thread {
private boolean running = true;
private boolean taskReady = false;
public synchronized void run() {
while (running) {
try { wait(); } catch (InterruptedException e) {}
if (running) doNetworkTask();
}
}
public synchronized void trigger() {
taskReady = true;
notify();
}
}

網路操作期間顯示載入動畫,大幅提升使用者體驗:
public class WaitCanvas extends Canvas {
private int frame = 0, maxFrames = 36;
private Timer timer;
private String message;
public WaitCanvas() {
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
frame = (frame + 1) % maxFrames;
repaint();
}
}, 0, 100);
}
public void setMessage(String msg) {
message = msg;
repaint();
}
protected void paint(Graphics g) {
int w = getWidth(), h = getHeight();
int r = Math.min(w, h) / 3;
int cx = w / 2, cy = h / 2;
g.setColor(0xFFFFFF);
g.fillRect(0, 0, w, h);
g.setColor(0x000000);
g.drawArc(cx - r, cy - r, 2*r, 2*r, 0, 360);
int angle = -frame * 10;
g.fillArc(cx - r, cy - r, 2*r, 2*r, angle + 90, 90);
g.fillArc(cx - r, cy - r, 2*r, 2*r, angle + 270, 90);
if (message != null) {
g.drawString(message, cx, h, Graphics.BOTTOM | Graphics.HCENTER);
}
}
}
WaitCanvas,設定提示訊息「連線中...」遵循這些原則,您的 J2ME 應用將在資源受限的行動裝置上提供流暢、專業的網路體驗。