HTTP 通信, 三种方式XML 解析,并通过 Hander 实现异步消息处理
来源:互联网 发布:珠海网络 编辑:程序博客网 时间:2024/04/21 00:11
本文出自:系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
作者:webabcd介绍
在 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
- 代码
- 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("下载出错");
- }
- }
- HTTP 通信, 三种方式XML 解析,并通过 Hander 实现异步消息处理
- HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- 系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- 系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- android HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理 (1)
- android HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理 (1)
- android HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理(2)
- android HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- 系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- 解析Hander消息处理机制
- Android中的异步消息处理机制Hander
- java处理XML三种解析方式比较
- xml三种解析方式
- Android实现XML解析技术的三种方式
- Android实现XML解析的三种方式
- XML三种解析方式简介以及JAVA实现
- 解析异步消息处理机制
- 探讨c++中的临时对象生命周期
- 迎接2012之集合和泛型(4)------栈的链式结构基本实现
- sqlserver 事务与锁定
- 正则基础
- Tkprof工具介绍和分析
- HTTP 通信, 三种方式XML 解析,并通过 Hander 实现异步消息处理
- 单步调试WebService的问题,水死了
- ibatis调用函数报错
- Maven、Ant
- 根据Url地址生成静态页C#--生成静态首页
- Google 协议解析开源技术protobuf 简介与例子
- 正则表达式基础
- linux上将文本行倒序输出的方法总结
- 使用WIX制作具有时间限制的安装包