• 从网络读取数据并动态的显示在ListView中


    这两天写了个小程序,使用了从网络读取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创建

    urce source = new InputSource(in);                  

    SAXParserFactory sax = SAXParserFactory.newInstance();

    der xmlReader = sax.newSAXParser().getXMLReader();                           

    xmlReader.setContentHandler(new ProductHandler());//ProductHandler是解析的句柄                        

    der.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);<span style="background-color: rgb(255, 255, 255); ">//保存价格</span>

            }

            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函数中调用

        

        @Override

        public void onClick(View v) {

            // TODO Auto-generated method stub

            httpGet();

        }

    });

    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() {

                

                @Override

                public void onClick(View v) {

                    // TODO Auto-generated method stub

                    httpGet();

                }

            });

            

            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>  

    doon的专栏

  • 相关阅读:
    def __unicode__(self): 或 def __str__(self):
    通过ORM创建数据库链接
    单表查询的API介绍
    数据库的查看以及建立数据库
    基础数据类型
    表单及数据库
    flag标志位
    Console面板小技巧:
    angular入门试水-基本指令理解
    构造方法
  • 原文地址:https://www.cnblogs.com/bmate/p/2352824.html
Copyright © 2020-2023  润新知