編輯:Android開發實例
介紹
在 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("下載出錯");
}
}
[源碼下載]
本文實例講述了Android編程實現QQ表情的發送和接收。分享給大家供大家參考,具體如下: 在自己做一個聊天應用練習的時候,需要用到表情,於是就想著模仿一下QQ表
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
吸引用戶的眼球,是我們至死不渝的追求;第一時間呈現最有價值的信息,簡明大方,告訴客戶,你的選擇是多麼的明智,這正是你尋覓已久的東西。 分組的應用場合還是很多的,有
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放