hc.setRequestMethod(HttpConnection.GET); // 默认即为GET
hc.setRequestProperty("User-Agent", USER_AGENT);
// get response code:
int code = hc.getResponseCode();
if(code!=HttpConnection.HTTP_OK) {
listener.onError(code, hc.getResponseMessage());
return;
}
// get size:
int size = (int)hc.getLength(); // 返回响应大小,或者-1如果大小无法确定
listener.onSetSize(size);
// 开始读响应:
input = hc.openInputStream();
int percent = 0; // percentage
int tmp_percent = 0;
int index = 0; // buffer index
int reads; // each byte
if(size!=(-1))
buffer = new byte[size]; // 响应大小已知,确定缓冲区大小
else
buffer = new byte[MAX_LENGTH]; // 响应大小未知,设定一个固定大小的缓冲区
while(!cancel) {
int len = buffer.length - index;
len = len>128 128 : len;
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 && input.available()>0) // 缓冲区已满,无法继续读取
listener.onError(601, "Buffer overflow.");
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 { // 清理资源
if(input!=null)
try { input.close(); } catch(IOException ioe) {}
if(hc!=null)
try { hc.close(); } catch(IOException ioe) {}
}
}
当下载完毕后,HttpWaitUI就获得了来自服务器的数据,要传递给下一个屏幕处理,HttpWaitUI必须包含对此屏幕的引用并通过一个setData(DataInputStream input)方法让下一个屏幕能非常方便地读取数据。因此,定义一个DataHandler接口:
public interface DataHandler {
void setData(DataInputStream input) throws IOException;
} HttpWaitUI响应HttpThread的onFinish事件并调用下一个屏幕的setData方法将数据传递给它并显示下一个屏幕:
public void onFinish(byte[] buffer, int size) {
byte[] data = buffer;
if(size!=buffer.length) {
data = new byte[size];
System.arraycopy(data, 0, buffer, 0, size);
}
DataInputStream input = null;
try {
input = new DataInputStream(new ByteArrayInputStream(data));
if(displayable instanceof DataHandler)
((DataHandler)displayable).setData(input);
else
System.err.println("[WARNING] Displayable object cannot handle data.");
ControllerMIDlet.replace(displayable);
}
catch(IOException ioe) { … }
} 以下载一则新闻为例,一个完整的HTTP GET请求过程如下:
首先,用户通过点击某个屏幕的命令希望阅读指定的一则新闻,在commandAction事件中,我们初始化HttpWaitUI和显示数据的NewsUI屏幕:
public void commandAction(Command c, Displayable d) {
HttpWaitUI wait = new HttpWaitUI("http://