科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件J2ME编程最佳实践之联网开发

J2ME编程最佳实践之联网开发

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

由于无线设备所能支持的网络协议非常有限,仅限于HTTP,Socket,UDP等几种协议。

作者:asklxf 来源:j2me开发网 2007年11月21日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
使用GET获取内容

  我们先讨论最简单的GET请求。GET请求只需向服务器发送一个URL,然后取得服务器响应即可。在HttpThread的run()方法中实现如下:

public void run() {
    HttpConnection hc = null;
    InputStream input = null;
    try {
        hc = (HttpConnection)Connector.open(url);
        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://192.168.0.1/news.do?id=1", new NewsUI());
    ControllerMIDlet.forward(wait);
}

  NewsUI实现DataHandler接口并负责显示下载的数据:

public class NewsUI extends Form implements DataHandler {
    public void setData(DataInputStream input) throws IOException {
        String title = input.readUTF();
        Date date = new Date(input.readLong());
        String text = input.readUTF();
        append(new StringItem("Title", title));
        append(new StringItem("Date", date.toString()));
        append(text);
    }
}

  服务器端只要以String, long, String的顺序依次写入DataOutputStream,MIDP客户端就可以通过DataInputStream依次取得相应的数据,完全不需要解析XML之类的文本,非常高效而且方便。

  需要获得联网数据的屏幕只需实现DataHandler接口,并向HttpWaitUI传入一个URL即可复用上述代码,无须关心如何连接网络以及如何处理用户中断连接。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章