從網路讀取資料並動態顯示在ListView中

來源:互聯網
上載者:User

這兩天寫了個小程式,使用了從網路讀取xml資料,並顯示在ListView中。

這裡面有幾個關鍵點:

  • 從網路讀取資料
  • SAX解析xml
  • 非同步填充ListView
先看下: 非常簡單的介面哈為了方便,我再自己的伺服器上,放了一個xml檔案,其內容主要是:
<?xml version="1.0"?><products><product><price>100</price><name>android dev</name><image src="image/android1.png"/></product><product><price>100</price><name>androiddev2</name><image src="image/android1.png"/></product><!-- 接著重複下去 .... --></products>
該程式,首先用一個AsyncTask新啟一個線程,來下載和解析xml;和主線程通過Handler對象來通訊。下載XML檔案通過HTTPGet來下載xml。這時apache提供的包,需要首先包含如下包:
import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;
代碼如下:(使用Get方法)
    protected String doInBackground(String... params) {        HttpGet httpRequest = new HttpGet(params[0]); //從url 建立一個HttpGet對象        HttpClient httpclient = new DefaultHttpClient();                //mShowHtml.setText("");        try {        HttpResponse httpResponse = httpclient.execute(httpRequest);                if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){//擷取http的傳回值代碼        HttpEntity entitiy = httpResponse.getEntity();                InputStream in = entitiy.getContent();//獲得內容        //解析xml,下面詳述        InputSource source = new InputSource(in);                SAXParserFactory sax = SAXParserFactory.newInstance();        XMLReader xmlReader = sax.newSAXParser().getXMLReader();                xmlReader.setContentHandler(new ProductHandler());                xmlReader.parse(source);                }        else {        //return "請求失敗!";        //mShowHtml.setText("請求失敗");        //Message mymsg = mMainHandler.obtainMessage();    //mymsg.obj = "請求失敗";    //mMainHandler.sendMessage(mymsg);        }                }catch(IOException e){        e.printStackTrace();        }catch(SAXException e) {        e.printStackTrace();        }catch(ParserConfigurationException e) {        e.printStackTrace();        }        return null;    }
解析XML使用SAX的解析方法,先包含必須得包
import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import org.xml.sax.helpers.DefaultHandler;

解析的代碼,正如上面所示:

                                                 //InputSource是解析源,可以通過一個InputStream建立         InputSource source = new InputSource(in);                         SAXParserFactory sax = SAXParserFactory.newInstance();          XMLReader xmlReader = sax.newSAXParser().getXMLReader();                                  xmlReader.setContentHandler(new ProductHandler());//ProductHandler是解析的控制代碼                          xmlReader.parse(source);

SAX主要使用ContentHandler介面來傳遞解析好得資料,不過,更經常使用的是DefaultHandler

    class ProductHandler extends DefaultHandler { //從 DefaultHandler繼承即可    private ProductInfo curProduct;    private String content;    //解析到一個標籤時調用    public void startElement(String uri, String localName, String name, org.xml.sax.Attributes attributes) throws SAXException {    if(localName.equals("product")) {//遇到product標籤,進行解析    curProduct = new ProductInfo();    }    else if(localName.equals("image")) {    //set name    curProduct.image = attributes.getValue("src");//提取image src屬性    }    super.startElement(uri, localName, name, attributes);    }        public void endElement(String uri, String localName, String name) throws SAXException{    if(localName.equals("product")) {//當解析到一個標籤結束時,發送一個訊息,把Product類作為參數傳遞    //send event    //get main handler    Message msg = mMainHandler.obtainMessage();    msg.obj = curProduct;    mMainHandler.sendMessage(msg);    //Log.i("Product:", curProduct.toString());    }    else if(localName.equals("name")) {    //set name    curProduct.name = content;//儲存名字    }    else if(localName.equals("price")) {    curProduct.price = Float.parseFloat(content);//儲存價格    }    super.endElement(uri, localName, name);    }    //這裡擷取具體的內容,是標籤下儲存的文本    public void characters (char[] ch, int start, int length)  throws SAXException    {    content = new String(ch, start, length);    //Log.i("Parser:" ,content);    super.characters(ch, start, length);    }    }

ProductInfo類的定義非常簡單

    class ProductInfo {    public String name;    public float price;    public String image;    public String toString() {    return "\nName:" + name +"\nPrice :" + price + "\nImage:" + image;    }    }
在AsyncTask中執行以上代碼
    public class GetHttpTask extends AsyncTask<String, Integer, String> {       public GetHttpTask() {       }        protected void onPreExecute() { //在進入線程之前執行。該函數在調用者線程內執行        }        protected String doInBackground(String... params) {//線程的執行主體        HttpGet httpRequest = new HttpGet(params[0]);  .................... //主要執行下載和解析的嗲嗎        return null;    }        protected void onPostExecute(String result) {//完成後調用        }    }

在主線程中,調用GetHttpTask的execute方法就可以執行

        btn.setOnClickListener(new View.OnClickListener() {//在onCreate函數中調用@Overridepublic void onClick(View v) {// TODO Auto-generated method stubhttpGet();}});

httpGet方法:

   void httpGet() {    GetHttpTask task = new GetHttpTask();    task.execute("http://192.168.1.111:8080/nfcdemo/products.xml");    }    
非同步傳遞訊息上面的例子中,在endElement函數中,發送了訊息,下面是接收訊息在主Activity中,聲明了一個Handler mHandler對象,並在 onCreate時,這樣做
        mMainHandler = new Handler() {        public  void handleMessage(Message msg) {        //mShowHtml.append((String)msg.obj);        if(msg.obj != null) {        ProductInfo prod = (ProductInfo)msg.obj;        Log.i("Prodcut:", prod.toString());        //mShowHtml.append(prod.toString());        HashMap<String, Object> map = new HashMap<String, Object>();        map.put("name", prod.name);        map.put("price", "RMB" + prod.price);        mlist.add(map); //mlist儲存了列表的具體資料        mProdList.notifyDataSetChanged();//mProdList是一個ListView對象,該函數引起ListView重讀資料        }        }        };        

這個過程的要點基本如上,貼上所有代碼吧!關於ListView的用法,可以參考http://blog.csdn.net/hellogv/article/details/4542668主代碼:

package com.test.http;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.HashMap;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParserFactory;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import org.xml.sax.helpers.DefaultHandler;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.SimpleAdapter;public class HtmltestActivity extends Activity {EditText mUrlText;//EditText mShowHtml;ListView mProducts;Handler mMainHandler;SimpleAdapter mProdList;ArrayList<HashMap<String,Object>> mlist;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                mUrlText = (EditText)findViewById(R.id.eturl);        //mShowHtml = (EditText)findViewById(R.id.etshowhtml);        mProducts = (ListView)findViewById(R.id.productList);                Button btn = (Button)findViewById(R.id.btngo);                        mlist = new ArrayList<HashMap<String, Object>>();        mProdList = new SimpleAdapter(this,        mlist,        R.layout.listitem,        new String[]{"name", "price"},        new int[]{R.id.prd_title, R.id.prd_price}        );                mProducts.setAdapter(mProdList);                        btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubhttpGet();}});                mMainHandler = new Handler() {        public  void handleMessage(Message msg) {        //mShowHtml.append((String)msg.obj);        if(msg.obj != null) {        ProductInfo prod = (ProductInfo)msg.obj;        Log.i("Prodcut:", prod.toString());        //mShowHtml.append(prod.toString());        HashMap<String, Object> map = new HashMap<String, Object>();        map.put("name", prod.name);        map.put("price", "RMB" + prod.price);        mlist.add(map);        mProdList.notifyDataSetChanged();        }        }        };            }        void httpGet() {    GetHttpTask task = new GetHttpTask();    task.execute("http://192.168.1.111:8080/nfcdemo/products.xml");    }        public class GetHttpTask extends AsyncTask<String, Integer, String> {       public GetHttpTask() {       }        protected void onPreExecute() {        }        protected String doInBackground(String... params) {        HttpGet httpRequest = new HttpGet(params[0]);        HttpClient httpclient = new DefaultHttpClient();                //mShowHtml.setText("");        try {        HttpResponse httpResponse = httpclient.execute(httpRequest);                if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){        HttpEntity entitiy = httpResponse.getEntity();                InputStream in = entitiy.getContent();                InputSource source = new InputSource(in);                SAXParserFactory sax = SAXParserFactory.newInstance();        XMLReader xmlReader = sax.newSAXParser().getXMLReader();                xmlReader.setContentHandler(new ProductHandler());                xmlReader.parse(source);                }        else {        //return "請求失敗!";        //mShowHtml.setText("請求失敗");        //Message mymsg = mMainHandler.obtainMessage();    //mymsg.obj = "請求失敗";    //mMainHandler.sendMessage(mymsg);        }                }catch(IOException e){        e.printStackTrace();        }catch(SAXException e) {        e.printStackTrace();        }catch(ParserConfigurationException e) {        e.printStackTrace();        }        return null;    }        protected void onPostExecute(String result) {    //mShowHtml.setText(result);    }    }        class ProductInfo {    public String name;    public float price;    public String image;    public String toString() {    return "\nName:" + name +"\nPrice :" + price + "\nImage:" + image;    }    }        class ProductHandler extends DefaultHandler {    private ProductInfo curProduct;    private String content;        public void startElement(String uri, String localName, String name, org.xml.sax.Attributes attributes) throws SAXException {    if(localName.equals("product")) {    curProduct = new ProductInfo();    }    else if(localName.equals("image")) {    //set name    curProduct.image = attributes.getValue("src");    }    super.startElement(uri, localName, name, attributes);    }        public void endElement(String uri, String localName, String name) throws SAXException{    if(localName.equals("product")) {    //send event    //get main handler    Message msg = mMainHandler.obtainMessage();    msg.obj = curProduct;    mMainHandler.sendMessage(msg);    //Log.i("Product:", curProduct.toString());    }    else if(localName.equals("name")) {    //set name    curProduct.name = content;    }    else if(localName.equals("price")) {    curProduct.price = Float.parseFloat(content);    }    super.endElement(uri, localName, name);    }        public void characters (char[] ch, int start, int length)  throws SAXException    {    content = new String(ch, start, length);    //Log.i("Parser:" ,content);    super.characters(ch, start, length);    }    }}
main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <LinearLayout        android:id="@+id/linearLayout1"        android:layout_width="match_parent"        android:layout_height="wrap_content" >        <EditText            android:id="@+id/eturl"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_weight="1" >            <requestFocus />        </EditText>        <Button            android:id="@+id/btngo"            android:layout_width="100dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="Go!" />    </LinearLayout>    <ListView        android:id="@+id/productList"        android:layout_width="match_parent"        android:layout_height="match_parent" >    </ListView></LinearLayout>
listitem.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <ImageView        android:id="@+id/product_icon"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"        android:src="@drawable/ic_launcher" />    <TextView        android:id="@+id/prd_title"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_toRightOf="@+id/product_icon"        android:text="TextView" />    <TextView        android:id="@+id/prd_price"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_alignParentTop="true"        android:text="TextView" /></RelativeLayout>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.