>al);publicv" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

在Android使用 SAX 方式進(jìn)行異步解析

系統(tǒng) 2418 0

對(duì) XML文件進(jìn)行解析有兩種:DOM方式和SAX方式。在Android應(yīng)用中,多采用SAX方式。這種方式是基于方法回調(diào)的,解析速度快,內(nèi)存消耗小。我們?cè)赟AX解析中增加了異步更新主線程的代碼,使用戶體驗(yàn)更佳。

一、主線程

主線程是 Activity,實(shí)現(xiàn)了自定義接口AsyncSaxResponse。該接口定義了3個(gè)方法,分別是:

public void parserUpdateNotify(ArrayList<Map<String,Object>> al);

public void parserStartNotify();

public void parserEndNotify(ArrayList<Map<String,Object>> al);

為簡(jiǎn)單起見,我們使用了 ListActivity,這樣不需要寫xml。整個(gè)Activity的代碼如下:

public class main extends ListActivity implements AsyncSaxResponse{

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super .onCreate(savedInstanceState);

// 登錄服務(wù)器,并取得結(jié)果

String url = this .getString(R.string. URL );

ColDetailParser handler = new ColDetailParser( this );

AsyncSaxHelper. execute (url, handler);

}

public void parserUpdateNotify(ArrayList<Map<String,Object>> al){

// Log.i("maps",""+ al );

// 構(gòu)建 listView 的適配器

SimpleAdapter adapter= new SimpleAdapter( this ,al,

android.R.layout. simple_list_item_2 , // SDK 庫(kù)中提供的一個(gè)包含兩個(gè) TextView layout

new String[]{ "rowname" , "data" }, // maps 中的兩個(gè) key

new int []{android.R.id. text1 ,android.R.id. text2 } // 兩個(gè) TextView id

);

this .setListAdapter(adapter);

// adapter.notifyDataSetChanged();

}

@Override

public void parserStartNotify() {

// TODO Auto-generated method stub

}

@Override

public void parserEndNotify(ArrayList<Map<String, Object>> al) {

// TODO Auto-generated method stub

}

}

onCreate方法中,我們使用了AsyncSaxHelper進(jìn)行xml文件的解析,其解析器是ColDetailParser(繼承了DefaultHandler),這兩個(gè)類后面介紹。

需要注意的是, ColDetailParser的構(gòu)造函數(shù)需要一個(gè)AsyncSaxResponse類的參數(shù)。我們把main.this傳遞給它,這樣main就必須實(shí)現(xiàn)AsyncSaxResponse的3個(gè)接口方法了。

parserUpdateNotify 方法中,我們對(duì)主線程UI進(jìn)行刷新。這個(gè)方法在SAX解析過程中會(huì)調(diào)用多次,比如每解析到一個(gè)節(jié)點(diǎn)就調(diào)用一次(具體看ColDetailParser類的代碼)。這樣,每當(dāng)解析到新的節(jié)點(diǎn),listview會(huì)重新綁定,從而產(chǎn)生列表被漸次刷新的效果。

另外兩個(gè)接口方法一個(gè)是在開始解析 xml文檔時(shí)調(diào)用,另一個(gè)是在xml文檔解析結(jié)束時(shí)調(diào)用,我們都采用了空實(shí)現(xiàn)。你可以分別在兩個(gè)方法中加入自己的代碼,比如文檔開始解析鎖住某些UI組件,一直到解析完成。

二、 AsyncSaxHelper類

AsyncSaxHelper類只有一個(gè)方法execute,用于構(gòu)造URL請(qǐng)求,然后調(diào)用Sax解析器進(jìn)行解析。

public class AsyncSaxHelper {

private static String tag = "AsyncSaxHelper" ;

public static void execute(String url,

DefaultHandler handler) { // 該方法通過 url 獲得 xml 并解析 xml 內(nèi)容為 Dept 對(duì)象數(shù)組

try // 異常處理

{

// url = Utils.getInstance().UrlWrap( url );

Log. w ( "getObjects url:" ,url);

URL _url = new URL(url);

// 構(gòu)建 Sax 解析器工廠

SAXParserFactory factory = SAXParserFactory. newInstance ();

// 使用 Sax 解析器工廠構(gòu)建 Sax 解析器

SAXParser parser = factory.newSAXParser();

// 使用 Sax 解析器構(gòu)建 xml Reader

XMLReader xmlreader = parser.getXMLReader();

// 綁定 handler xml reader

xmlreader.setContentHandler(handler);

// 對(duì)于中文編碼,要進(jìn)行如下處理==========

Log. w ( "open stream" , "" + new java.util.Date().getTime());

InputStream stream = _url.openStream();

InputStreamReader sr = new InputStreamReader(stream, "gb2312" );

InputSource is = new InputSource(sr);

// ========================

Log. w ( "xml parse bengin" , "" + new java.util.Date().getTime());

// 讀取 xml ,進(jìn)行 sax 解析

xmlreader.parse(is);

// Log.i(tag,handler.getObjects().toString());

// 將解析結(jié)果返回

// return handler.getObjects();

} catch (Exception ee) {

ee.printStackTrace();

// return null;

}

}

}

你可以進(jìn)一步改進(jìn)這個(gè)方法,將其封裝為線程方法。

三、 SAX解析器

真正的解析動(dòng)作由 ColDetailParser完成,ColDetailParser繼承了DefaultHandler并實(shí)現(xiàn)其5個(gè)方法:

public class ColDetailParser extends DefaultHandler { // 繼承 DefaultHandler, 方便進(jìn)行 sax

// 解析

final static String tag = "ColDetailParser" ;

Map<String, Object> _map ; // 臨時(shí)變量,用于保存解析過程中的元素值

ArrayList<Map<String, Object>> _maps ;

int flag = 0;

boolean isTable = false ;

private AsyncSaxResponse delegate ;

ColDetailParser(AsyncSaxResponse delegate) {

this . delegate =delegate;

}

// 下面通過重載 DefaultHandler 5 個(gè)方法來實(shí)現(xiàn) sax 解析

public void startDocument() throws SAXException { // 這個(gè)方法在解析 xml 文檔的一開始執(zhí)行 , 一般我們需要在該方法中初始化解析過程中有可能用到的變量

Log. w ( "start document" , "" + new java.util.Date().getTime());

_maps = new ArrayList<Map<String,Object>>();

if ( delegate != null ){

try {

// 獲取 delegate parserUpdateNotify 并調(diào)用 , 該方法有一個(gè) ArrayList 參數(shù)

Method m = delegate .getClass().getMethod( "parserStartNotify" );

if (m != null ) m.invoke( delegate );

} catch (Exception e) {

e.printStackTrace();

}

}

}

public void endDocument() throws SAXException { // 這個(gè)方法在整個(gè) xml 文檔解析結(jié)束時(shí)執(zhí)行 , 一般需要在該方法中返回或保存整個(gè)文檔解析解析結(jié)果 , 但由于

// 我們已經(jīng)在解析過程中把結(jié)果保持在全局變量中 , 所以這里什么也不做

Log. w ( "end document" , "" + new java.util.Date().getTime());

if ( delegate != null ){

try {

// 獲取 delegate parserUpdateNotify 并調(diào)用 , 該方法有一個(gè) ArrayList 參數(shù)

Method m = delegate .getClass().getMethod( "parserEndNotify" , new Class[]{ArrayList. class });

if (m != null ) m.invoke( delegate , _maps );

} catch (Exception e) {

e.printStackTrace();

}

}

}

public void startElement(String namespaceURI, String localName,

String qName, Attributes atts) throws SAXException { // 這個(gè)方法在解析標(biāo)簽開始標(biāo)記時(shí)執(zhí)行 , 我們關(guān)心 2 個(gè)元素,在這里判斷這 2 個(gè)元素并做上對(duì)應(yīng)標(biāo)記

if (localName.equals( "table" )) { // 若是 table 標(biāo)簽 , 初始化 _map

_map = new HashMap<String, Object>();

isTable = true ;

return ;

}

if ( isTable &&localName.equals( "row_id" )) { // 若是 row_id 標(biāo)簽 , flag 標(biāo)志為 1,

flag = 1;

return ;

}

if ( isTable &&localName.equals( "name" )) { // 若是 name 標(biāo)簽 , flag 標(biāo)志為 2,

flag = 2;

return ;

}

if ( isTable &&localName.equals( "data" )) { // 若是 data 標(biāo)簽 , flag 標(biāo)志為 3,

flag = 3;

return ;

}

}

public void characters( char ch[], int start, int length) { // 這個(gè)方法在解析標(biāo)簽內(nèi)容 ( 即開始標(biāo)記-結(jié)束標(biāo)記之間的部分 ) 時(shí)執(zhí)行 , 一般我們?cè)诶镞@獲取元素體內(nèi)容 , 在本例中,我們只關(guān)心 3 個(gè)元素體

String theString = new String(ch, start, length); // 獲取元素體內(nèi)容

switch ( flag ) {

case 1:

if ( _map == null )Log. i ( tag , "_map is null" );

_map .put( "rowid" , theString);

break ;

case 2:

_map .put( "rowname" , theString);

break ;

case 3:

_map .put( "data" , theString);

default :

break ;

}

flag = 0; // 標(biāo)記歸零

}

public void endElement(String namespaceURI, String localName, String qName)

throws SAXException { // 這個(gè)方法在解析標(biāo)簽結(jié)束標(biāo)記時(shí)執(zhí)行 , 一般我們需要在該方法保存元素內(nèi)容

if (localName.equals( "table" )) { // table 標(biāo)簽結(jié)束 , _map 保存到 _maps 數(shù)組

Log. w ( "table element" , "" + new java.util.Date().getTime());

_maps .add( _map );

isTable = false ;

flag =0;

if ( delegate != null ){

try {

// 獲取 delegate parserUpdateNotify 并調(diào)用 , 該方法有一個(gè) ArrayList 參數(shù)

Method m = delegate .getClass().getMethod( "parserUpdateNotify" , new Class[]{ArrayList. class });

if (m != null ) m.invoke( delegate , _maps );

} catch (Exception e) {

e.printStackTrace();

}

}

return ;

}

}

}

真正由意思的事情發(fā)生在構(gòu)造方法里。我們傳遞了一個(gè) AsyncSaxResponse接口對(duì)象給構(gòu)造方法,并將其保存到實(shí)例變量delegate里。這樣在適當(dāng)?shù)臅r(shí)候(比如在startDocument、endDocument和endElement里)就可以通過delegate對(duì)象回調(diào)主線程的3個(gè)接口方法了。通過這種方式,實(shí)現(xiàn)了異步解析中同步更新主線程的UI。

運(yùn)行程序,模擬器界面和 Logcat輸出信息如下:

在Android使用 SAX 方式進(jìn)行異步解析 在Android使用 SAX 方式進(jìn)行異步解析

在Android使用 SAX 方式進(jìn)行異步解析


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 中文字幕一区二区三区四区 | 天天色天天舔 | 成年人免费网址 | 国产精品第六页 | 日本午夜在线视频 | 国产伦精品一区二区三区免费观看 | 午夜影院免费在线观看 | 久久香蕉久久 | 国产精品爱久久久久久久小 | 亚洲综合极品香蕉久久网 | 国产欧美精品综合一区 | 亚洲色婷婷综合开心网 | 日日狠狠久久偷偷四色综合免费 | 2020国产免费久久精品99 | 四虎影视免费永久在线观看黄 | 狠狠激情 | 免费看一级特黄a大片 | 在线色资源 | 国产草比 | 国产午夜亚洲精品久久999 | 99尹人香蕉国产免费天天在线 | 五月色综合| 俄罗斯色视频 | 中文字幕日韩精品麻豆系列 | 欧美专区亚洲 | 欧美日韩中文一区 | 奇米影视第四色7777 | 男人天堂成人 | 国产美女一级高清免费观看 | 寂寞午夜影院 | 国产成人亚洲精品91专区手机 | 久久国产视频一区 | 成人欧美一区二区三区黑人3p | 亚洲精品一区二区久久 | 黄色片网站大全 | 久久夜夜视频 | 国产一区二区三区久久精品小说 | 天天干天天操天天插 | 国产最新网站 | 国产精品全国探花泡良大师 | 久一视频在线观看 |