android HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理

来源:互联网 发布:快速备案淘宝交易 编辑:程序博客网 时间:2024/04/25 19:20
package com.webabcd.handler;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;import webabcd.util.DownloadManagerAsync;public class Main extends Activity implements        DownloadManagerAsync.OnDownloadCompleteListener,        DownloadManagerAsync.OnDownloadUpdateListener,        DownloadManagerAsync.OnDownloadErrorListener {        TextView txt;        /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                DownloadManagerAsync manager = new DownloadManagerAsync();        manager.setOnDownloadCompleteListener(this);        manager.setOnDownloadUpdateListener(this);        manager.download("http://files.cnblogs.com/webabcd/Android.rar", "/sdcard/Android.rar");                txt = (TextView) this.findViewById(R.id.txt);        txt.setText("开始下载");    }    public void onDownloadComplete(DownloadManagerAsync manager, Object result) {        txt.setText("下载完成");    }        public void onDownloadUpdate(DownloadManagerAsync manager, int percent) {        txt.setText("下载进度:" + String.valueOf(percent) + "%");    }        public void onDownloadError(DownloadManagerAsync manager, Exception e) {        txt.setText("下载出错");    }}

在 Android 中与服务端做 HTTP 通信,解析 XML,通过 Handler 实现异步消息处理 
HTTP 通信 - 与服务端做 HTTP 通信,分别以 GET 方式和 POST 方式做演示 
XML 解析 - 可以用两种方式解析 XML,分别是 DOM 方式和 SAX 方式 

异步消息处理 - 通过 Handler 实现异步消息处理,以一个自定义的异步下载类来说明 Handler 的用法


1、HTTP 通信和 XML 解析的 Demo 
MySAXHandler.java


package com.webabcd.communication;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;// 继承 DefaultHandler 以实现指定 XML 的 SAX 解析器// DOM - W3C 标准,需要把 xml 数据全部加载完成后才能对其做解析,可对树做任意遍历// SAX - 流式解析,通过事件模型解析 xml,只能顺序解析public class MySAXHandler extends DefaultHandler {    private boolean mIsTitleTag = false;    private boolean mIsSalaryTag = false;    private boolean mIsBirthTag = false;    private String mResult = "";        // 打开 xml 文档的回调函数    @Override    public void startDocument() throws SAXException {        // TODO Auto-generated method stub        super.startDocument();    }        // 关闭 xml 文档的回调函数    @Override    public void endDocument() throws SAXException {        // TODO Auto-generated method stub        super.endDocument();    }        // 一发现元素开始标记就回调此函数    @Override    public void startElement(String uri, String localName, String qName,            Attributes attributes) throws SAXException {        if (localName == "title")            mIsTitleTag = true;        else if (localName == "salary")            mIsSalaryTag = true;        else if (localName == "dateOfBirth")            mIsBirthTag = true;        else if (localName == "employee")            mResult += "\nname:" + attributes.getValue("name");        }    // 一发现元素结束标记就回调此函数    @Override    public void endElement(String uri, String localName, String qName)            throws SAXException {        if (localName == "title")            mIsTitleTag = false;        else if (localName == "salary")            mIsSalaryTag = false;        else if (localName == "dateOfBirth")            mIsBirthTag = false;    }    // 一发现元素值或属性值就回调此函数    @Override    public void characters(char[] ch, int start, int length)            throws SAXException {        if (mIsTitleTag)            mResult += new String(ch, start, length);        else if (mIsSalaryTag)            mResult += " salary:" + new String(ch, start, length);        else if (mIsBirthTag)            mResult += " dateOfBirth:" + new String(ch, start, length);    }        public String getResult(){        return mResult;    }}


Main.java


package com.webabcd.communication;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.message.BasicNameValuePair;import org.apache.http.protocol.HTTP;import org.apache.http.util.ByteArrayBuffer;import org.apache.http.util.EncodingUtils;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;import org.xml.sax.XMLReader;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class Main extends Activity {        private TextView textView;        /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                textView = (TextView) this.findViewById(R.id.textView);                Button btn1 = (Button) this.findViewById(R.id.btn1);        btn1.setText("http get demo");        btn1.setOnClickListener(new Button.OnClickListener() {            public void onClick(View v) {                httpGetDemo();            }        });                Button btn2 = (Button) this.findViewById(R.id.btn2);        btn2.setText("http post demo");        btn2.setOnClickListener(new Button.OnClickListener() {            public void onClick(View v) {                httpPostDemo();            }        });                Button btn3 = (Button) this.findViewById(R.id.btn3);        // DOM - Document Object Model        btn3.setText("DOM 解析 XML");        btn3.setOnClickListener(new Button.OnClickListener() {            public void onClick(View v) {                DOMDemo();            }        });                Button btn4 = (Button) this.findViewById(R.id.btn4);        // SAX - Simple API for XML        btn4.setText("SAX 解析 XML");        btn4.setOnClickListener(new Button.OnClickListener() {            public void onClick(View v) {                SAXDemo();            }        });    }        // Android 调用 http 协议的 get 方法    // 本例:以 http 协议的 get 方法获取远程页面响应的内容    private void httpGetDemo(){        try {            // 模拟器测试时,请使用外网地址            URL url = new URL("http://xxx.xxx.xxx");            URLConnection con = url.openConnection();                        String result = "http status code: " + ((HttpURLConnection)con).getResponseCode() + "\n";            // HttpURLConnection.HTTP_OK                        InputStream is = con.getInputStream();            BufferedInputStream bis = new BufferedInputStream(is);            ByteArrayBuffer bab = new ByteArrayBuffer(32);            int current = 0;            while ( (current = bis.read()) != -1 ){                bab.append((byte)current);            }            result += EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8);                        bis.close();            is.close();            textView.setText(result);        } catch (Exception e) {            textView.setText(e.toString());        }    }        // Android 调用 http 协议的 post 方法    // 本例:以 http 协议的 post 方法向远程页面传递参数,并获取其响应的内容    private void httpPostDemo(){        try {            // 模拟器测试时,请使用外网地址            String url = "http://5billion.com.cn/post.php";            Map<String, String> data = new HashMap<String, String>();            data.put("name", "webabcd");            data.put("salary", "100");                        DefaultHttpClient httpClient = new DefaultHttpClient();            HttpPost httpPost = new HttpPost(url);            ArrayList<BasicNameValuePair> postData = new ArrayList<BasicNameValuePair>();            for (Map.Entry<String, String> m : data.entrySet()) {                postData.add(new BasicNameValuePair(m.getKey(), m.getValue()));            }            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postData, HTTP.UTF_8);            httpPost.setEntity(entity);                        HttpResponse response = httpClient.execute(httpPost);                        String result = "http status code: " + response.getStatusLine().getStatusCode() + "\n";            // HttpURLConnection.HTTP_OK                        HttpEntity httpEntity = response.getEntity();                        InputStream is = httpEntity.getContent();            result += convertStreamToString(is);                        textView.setText(result);        } catch (Exception e) {            textView.setText(e.toString());            }    }        // 以 DOM 方式解析 XML(xml 数据详见 res/raw/employee.xml)    private void DOMDemo(){        try    {            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();            Document doc = docBuilder.parse(this.getResources().openRawResource(R.raw.employee));            Element rootElement = doc.getDocumentElement();            NodeList employeeNodeList = rootElement.getElementsByTagName("employee");                        textView.setText("DOMDemo" + "\n");            String title = rootElement.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();            textView.append(title);            for (int i=0; i<employeeNodeList.getLength(); i++){                Element employeeElement = ((Element)employeeNodeList.item(i));                String name = employeeElement.getAttribute("name");                String salary = employeeElement.getElementsByTagName("salary").item(0).getFirstChild().getNodeValue();                String dateOfBirth = employeeElement.getElementsByTagName("dateOfBirth").item(0).getFirstChild().getNodeValue();                textView.append("\nname: "+name+" salary: "+salary+" dateOfBirth: " + dateOfBirth);            }        } catch (Exception e) {            textView.setText(e.toString());            }    }        // 以 SAX 方式解析 XML(xml 数据详见 res/raw/employee.xml)    // SAX 解析器的实现详见 MySAXHandler.java    private void SAXDemo(){        try    {            SAXParserFactory saxFactory = SAXParserFactory.newInstance();            SAXParser parser = saxFactory.newSAXParser();            XMLReader reader = parser.getXMLReader();                        MySAXHandler handler = new MySAXHandler();            reader.setContentHandler(handler);            reader.parse(new InputSource(this.getResources().openRawResource(R.raw.employee)));            String result = handler.getResult();            textView.setText("SAXDemo" + "\n");            textView.append(result);        } catch (Exception e) {            textView.setText(e.toString());            }    }    // 辅助方法,用于把流转换为字符串    private String convertStreamToString(InputStream is) {        BufferedReader reader = new BufferedReader(new InputStreamReader(is));        StringBuilder sb = new StringBuilder();          String line = null;        try {            while ((line = reader.readLine()) != null) {                sb.append(line + "\n");            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                is.close();            } catch (IOException e) {                e.printStackTrace();            }        }          return sb.toString();    }}

2、用 Handler 来实现异步消息处理,以一个可以实时汇报下载进度的异步下载类为例
开发一个 Android 类库,本例中此类库名为 webabcd_util


New -> Java Project
项目上点右键 -> Build Path -> Add Libraries -> User Library -> User Libraries -> New -> 为类库起个名字 -> 选中这个类库 -> Add JARs 导入 Android 的 jar 包
项目上点右键 -> Build Path -> Add Libraries -> User Library -> 选择 Android 库

DownloadManagerAsync.java


package webabcd.util;import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;import java.net.URLConnection;import org.apache.http.protocol.HTTP;import android.os.Handler;import android.os.Message;import android.util.Log;// 以一个实例,即异步下载,来演示 Android 的异步消息处理(用 Handler 的方式)public class DownloadManagerAsync {    public DownloadManagerAsync() {    }    // 实例化自定义的 Handler    EventHandler mHandler = new EventHandler(this);    // 按指定 url 地址下载文件到指定路径    public void download(final String url, final String savePath) {        new Thread(new Runnable() {            public void run() {                try {                    sendMessage(FILE_DOWNLOAD_CONNECT);                    URL sourceUrl = new URL(url);                    URLConnection conn = sourceUrl.openConnection();                    InputStream inputStream = conn.getInputStream();                    int fileSize = conn.getContentLength();                    File savefile = new File(savePath);                    if (savefile.exists()) {                        savefile.delete();                    }                    savefile.createNewFile();                    FileOutputStream outputStream = new FileOutputStream(                            savePath, true);                    byte[] buffer = new byte[1024];                    int readCount = 0;                    int readNum = 0;                    int prevPercent = 0;                    while (readCount < fileSize && readNum != -1) {                        readNum = inputStream.read(buffer);                        if (readNum > -1) {                            outputStream.write(buffer);                            readCount = readCount + readNum;                            int percent = (int) (readCount * 100 / fileSize);                            if (percent > prevPercent) {                                // 发送下载进度信息                                sendMessage(FILE_DOWNLOAD_UPDATE, percent,                                        readCount);                                prevPercent = percent;                            }                        }                    }                    outputStream.close();                    sendMessage(FILE_DOWNLOAD_COMPLETE, savePath);                } catch (Exception e) {                    sendMessage(FILE_DOWNLOAD_ERROR, e);                    Log.e("MyError", e.toString());                }            }        }).start();    }    // 读取指定 url 地址的响应内容    public void download(final String url) {        new Thread(new Runnable() {            public void run() {                try {                    sendMessage(FILE_DOWNLOAD_CONNECT);                    URL sourceUrl = new URL(url);                    URLConnection conn = sourceUrl.openConnection();                    conn.setConnectTimeout(3000);                    BufferedReader reader = new BufferedReader(                            new InputStreamReader(conn.getInputStream(),                                    HTTP.UTF_8));                    String line = null;                    StringBuffer content = new StringBuffer();                    while ((line = reader.readLine()) != null) {                        content.append(line);                    }                    reader.close();                    sendMessage(FILE_DOWNLOAD_COMPLETE, content.toString());                } catch (Exception e) {                    sendMessage(FILE_DOWNLOAD_ERROR, e);                    Log.e("MyError", e.toString());                }            }        }).start();    }    // 向 Handler 发送消息    private void sendMessage(int what, Object obj) {        // 构造需要向 Handler 发送的消息        Message msg = mHandler.obtainMessage(what, obj);        // 发送消息        mHandler.sendMessage(msg);    }    private void sendMessage(int what) {        Message msg = mHandler.obtainMessage(what);        mHandler.sendMessage(msg);    }    private void sendMessage(int what, int arg1, int arg2) {        Message msg = mHandler.obtainMessage(what, arg1, arg2);        mHandler.sendMessage(msg);    }    private static final int FILE_DOWNLOAD_CONNECT = 0;    private static final int FILE_DOWNLOAD_UPDATE = 1;    private static final int FILE_DOWNLOAD_COMPLETE = 2;    private static final int FILE_DOWNLOAD_ERROR = -1;    // 自定义的 Handler    private class EventHandler extends Handler {        private DownloadManagerAsync mManager;        public EventHandler(DownloadManagerAsync manager) {            mManager = manager;        }        // 处理接收到的消息        @Override        public void handleMessage(Message msg) {            switch (msg.what) {            case FILE_DOWNLOAD_CONNECT:                if (mOnDownloadConnectListener != null)                    mOnDownloadConnectListener.onDownloadConnect(mManager);                break;            case FILE_DOWNLOAD_UPDATE:                if (mOnDownloadUpdateListener != null)                    mOnDownloadUpdateListener.onDownloadUpdate(mManager,                            msg.arg1);                break;            case FILE_DOWNLOAD_COMPLETE:                if (mOnDownloadCompleteListener != null)                    mOnDownloadCompleteListener.onDownloadComplete(mManager,                            msg.obj);                break;            case FILE_DOWNLOAD_ERROR:                if (mOnDownloadErrorListener != null)                    mOnDownloadErrorListener.onDownloadError(mManager,                            (Exception) msg.obj);                break;            default:                break;            }        }    }    // 定义连接事件    private OnDownloadConnectListener mOnDownloadConnectListener;    public interface OnDownloadConnectListener {        void onDownloadConnect(DownloadManagerAsync manager);    }    public void setOnDownloadConnectListener(OnDownloadConnectListener listener) {        mOnDownloadConnectListener = listener;    }    // 定义下载进度更新事件    private OnDownloadUpdateListener mOnDownloadUpdateListener;    public interface OnDownloadUpdateListener {        void onDownloadUpdate(DownloadManagerAsync manager, int percent);    }    public void setOnDownloadUpdateListener(OnDownloadUpdateListener listener) {        mOnDownloadUpdateListener = listener;    }    // 定义下载完成事件    private OnDownloadCompleteListener mOnDownloadCompleteListener;    public interface OnDownloadCompleteListener {        void onDownloadComplete(DownloadManagerAsync manager, Object result);    }    public void setOnDownloadCompleteListener(            OnDownloadCompleteListener listener) {        mOnDownloadCompleteListener = listener;    }    // 定义下载异常事件    private OnDownloadErrorListener mOnDownloadErrorListener;    public interface OnDownloadErrorListener {        void onDownloadError(DownloadManagerAsync manager, Exception e);    }    public void setOnDownloadErrorListener(OnDownloadErrorListener listener) {        mOnDownloadErrorListener = listener;    }}


调用上面的自定义的 Android 类库

项目上点右键 -> Properties -> Java Build Path -> Projects -> Add 引用上面的类库

Main.java




原创粉丝点击