博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
阅读量:5949 次
发布时间:2019-06-19

本文共 15059 字,大约阅读时间需要 50 分钟。





系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理


作者:



介绍

在 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("下载出错"); 
        } 
}
 


OK
     本文转自webabcd 51CTO博客,原文链接: http://blog.51cto.com/webabcd/342102
,如需转载请自行联系原作者
你可能感兴趣的文章
OpenGL 4 : 一个漂亮的心 For you, My Love
查看>>
2007年硕士研究生面试时的英文自我介绍
查看>>
POJ1789:Truck History(Prim算法)
查看>>
SD卡
查看>>
使用servletAPI三种方式简单示例
查看>>
单片机不同晶振怎么计算延迟时间?
查看>>
视频会议十大开源项目排行
查看>>
SQL Server Management Studio 简单使用说明
查看>>
【前端】javascript判断undefined、null、NaN;字符串包含等
查看>>
玩转iOS开发 - 数据缓存
查看>>
李洪强-C语言3-数组
查看>>
C# 6.0的字典(Dictionary)的语法
查看>>
使用ShareSDK实现第三方授权登录、分享以及获取用户资料效果,项目中包含:源码+效果图+项目结构图...
查看>>
三级联动效果
查看>>
Sprite和UI Image的区别
查看>>
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql/mysql.sock' (2)
查看>>
python练习笔记——丑数的计算
查看>>
OpenCV + python 实现人脸检测(基于照片和视频进行检测)
查看>>
XSS 前端防火墙 —— 天衣无缝的防护
查看>>
Node.js umei图片批量下载Node.js爬虫1.00
查看>>