zoukankan      html  css  js  c++  java
  • Android中使用sax解析XML

                在Android中使用XML解析数据是非常常见的一件事,但是使用那种方式比较好呢,因为基于Android开发的硬件毕竟性能一般有限,主要是手机和嵌入式设备。一般我们使用sax解析。速度比较快,也不大耗内存。当然负面影响也是有的,编码比较多,而且比较复杂些。下面我们来看一个例子:

                首先我们实现一个xml的实体类,如下:

              //收藏明细实体类
    public class TPFavouriteItemModel {
        
            public static String SN = "sn";
            public static String IMAGEURL = "productimageurl";
            public static String NAME = "productname";
            public static String PRICE="productprice";
            //产品ID
            private String Sn;
            //产品图片路径
             private String ProductImageUrl;
             //产品名称
            private String ProductName;
            //产品价格
            private String ProductPrice;
            //Construct Function
            public TPFavouriteItemModel() {
               
            }
            //Construct Function
            public TPFavouriteItemModel(String sn,String imageUrl, String name,String price) {
                this.Sn=sn;
                this.ProductImageUrl = imageUrl;
                this.ProductName = name;
                this.ProductPrice=price;
            }
            //获取产品ID
            public String getProductID()
            {
                return Sn;
            }
            //获取产品图片路径
            public String getProductImageUrl() {
                return ProductImageUrl;
            }
            //获取产品名称
            public String getProductName() {
                return ProductName;
            }
            //获取产品价格
            public String getProductPrice() {
                return ProductPrice;
            }
            //设置产品图片路径
            public void setProductID(String str) {
                Sn=str;
            }
            //设置产品图片路径
            public void setProductImageUrl(String str)
            {
                ProductImageUrl=str;
            }
            //设置产品名称
            public void setProductName(String str)
            {
                ProductName=str;
            }
            //设置产品价格
            public void setProductPrice(String str)
            {
                ProductPrice=str;
            }
    }

    其次我们要实现一个对应的Handler类来处理xml文档,这里面定义了很多xml文档的事件,代码如下:

    //收藏夹明细handler
    public class TPFavouriteItemHandler extends DefaultHandler {
        
        TPFavouriteItemModel favouriteItem;
        TPFavouriteItemFeed favouriteFeed;
        
        //收藏夹明细数据类中的变量状态
        final int CI_PRODUCTID=1;
        final int CI_PRODUCTIMAGEURL=2;
        final int CI_PRODUCTNAME=3;
        final int CI_PRODUCTPRICE=4;
        
        int currentstate = 0;
        //收藏夹构造类
        public TPFavouriteItemHandler()
        {
        }
        //获取收藏夹填充类
        public TPFavouriteItemFeed getCartFeed()
        {
            return favouriteFeed;
        }
        
        @Override
        public void startDocument() throws SAXException {
            // TODO Auto-generated method stub
            favouriteItem = new TPFavouriteItemModel();
            favouriteFeed = new TPFavouriteItemFeed();
        }
        
        @Override
        public void endDocument() throws SAXException {
            // TODO Auto-generated method stub
        }
        
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            // TODO Auto-generated method stub
            if(localName.equals("favourit")){
                currentstate = 0;
                return;
            }
            if(localName.equals("item")){
                favouriteItem = new TPFavouriteItemModel();
                return;
            }
            if(localName.equals("sn")){
                currentstate = CI_PRODUCTID;
                return;
            }
            if(localName.equals("productimageurl")){
                currentstate = CI_PRODUCTIMAGEURL;
                return;
            }
            if(localName.equals("productname")){
                currentstate = CI_PRODUCTNAME;
                return;
            }
            if(localName.equals("productprice")){
                currentstate = CI_PRODUCTPRICE;
                return;
            }
            currentstate = 0;
        }
        
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            // TODO Auto-generated method stub
            if(localName.equals("item")){
                favouriteFeed.addItem(favouriteItem);
                return;
            }
        }
        
        //填充值
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            // TODO Auto-generated method stub
            String theString = new String(ch, start, length);
            switch(currentstate){
            case CI_PRODUCTID:
                favouriteItem.setProductID(theString);
                currentstate = 0;
                break;
            case CI_PRODUCTIMAGEURL:
                favouriteItem.setProductImageUrl(theString);
                currentstate = 0;
                break;
            case CI_PRODUCTNAME:
                favouriteItem.setProductName(theString);
                currentstate = 0;
                break;
            case CI_PRODUCTPRICE:
                favouriteItem.setProductPrice(theString);
                currentstate = 0;
                break;
            default:
                return;
            }
        }

    接下来我们要实现一个对应的Adapter类,因为我们是要解析一个收藏夹的xml文档,代码如下:

    public class FavourityListAdapter extends ArrayAdapter<TPFavouriteItemModel> {
        
         private ListView listView;
         private AsyncImageLoader asyncImageLoader;
        
         public FavourityListAdapter(Activity activity, List<TPFavouriteItemModel> favourites, ListView listView) {
                super(activity, 0, favourites);
                this.listView = listView;
                asyncImageLoader = new AsyncImageLoader();
            }
        
         public View getView(int position, View convertView, ViewGroup parent) {
                Activity activity = (Activity) getContext();

                // Inflate the views from XML
                View rowView = convertView;
                ViewCache viewCache;
                if (rowView == null) {
                    LayoutInflater inflater = activity.getLayoutInflater();
                    rowView = inflater.inflate(R.layout.favourite_item, null);
                    viewCache = new ViewCache(rowView);
                    rowView.setTag(viewCache);
                } else {
                    viewCache = (ViewCache) rowView.getTag();
                }
                TPFavouriteItemModel favouriteItem = getItem(position);

                // Load the image and set it on the ImageView
                String imageUrl = favouriteItem.getProductImageUrl();
                ImageView imageView = viewCache.getPruductImageView();
                imageView.setTag(imageUrl);
                Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {
                    public void imageLoaded(Drawable imageDrawable, String imageUrl) {
                        ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
                        if (imageViewByTag != null) {
                            imageViewByTag.setImageDrawable(imageDrawable);
                        }
                    }
                });
                if (cachedImage == null) {
                    imageView.setImageResource(R.drawable.default_image);
                }else{
                    imageView.setImageDrawable(cachedImage);
                }
                // Set the text on the Product Name
                TextView tvName = viewCache.getProductNameView();
                tvName.setText(favouriteItem.getProductName());
                // Set the text on the Product Price
                TextView tvPrice = viewCache.getProductPriceView();
                tvPrice.setText(favouriteItem.getProductPrice());

                return rowView;
            }
        
    }

    因为收藏夹中包括图片显示,而图片加载可能会比较慢,为了取得比较好的用户体验我们要采用异步

    方式加载,因此我们定义了一个AsyncImageLoader类,它的具体实现如下所示:

    public class AsyncImageLoader {
         private HashMap<String, SoftReference<Drawable>> imageCache;
          
         public AsyncImageLoader() {
             imageCache = new HashMap<String, SoftReference<Drawable>>();
         }
     
         public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
             if (imageCache.containsKey(imageUrl)) {
                 SoftReference<Drawable> softReference = imageCache.get(imageUrl);
                 Drawable drawable = softReference.get();
                 if (drawable != null) {
                     return drawable;
                 }
             }
             final Handler handler = new Handler() {
                 public void handleMessage(Message message) {
                     imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
                 }
             };
             new Thread() {
                 @Override
                 public void run() {
                     Drawable drawable = loadImageFromUrl(imageUrl);
                     imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
                     Message message = handler.obtainMessage(0, drawable);
                     handler.sendMessage(message);
                 }
             }.start();
             return null;
         }
     
        public static Drawable loadImageFromUrl(String url) {
            URL m;
            InputStream i = null;
            try {
                m = new URL(url);
                i = (InputStream) m.getContent();
            } catch (MalformedURLException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Drawable d = Drawable.createFromStream(i, "src");
            return d;
        }
     
         public interface ImageCallback {
             public void imageLoaded(Drawable imageDrawable, String imageUrl);
         }
    }

    接着我们来看看收藏夹的布局文件:

    <?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">
      <ListView android:id="@+id/lvFavourite" android:layout_width="wrap_content"
                  android:layout_height="fill_parent"
      >
      </ListView>

    </LinearLayout>

    下面这个是收藏夹的明细画面,放置在ListView中的:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 收藏夹画面的明细条目 -->
    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent" android:orientation="horizontal"
      android:layout_height="fill_parent"
      >
      <LinearLayout android:id="@+id/llItem" android:layout_width="120dip"
      android:layout_height="100dip" android:orientation="vertical">
            <!-- 商品图片 -->
          <ImageView android:id="@+id/ivProduct" android:layout_width="80dip"
           android:layout_height="60dip"/>
           <!-- 商品价格 -->
          <TextView android:id="@+id/tvProductPrice" android:layout_width="wrap_content"
          android:layout_height="40dip"/>
          
      </LinearLayout>
     
      <LinearLayout android:id="@+id/llItemProduct" android:layout_width="180dip"
      android:layout_height="100dip"  
      >
            <!-- 商品名称 -->
            <TextView android:id="@+id/tvProductName" android:layout_width="wrap_content"
          android:layout_height="100dip" android:layout_marginTop="60dip"/>
            
      </LinearLayout>
      <LinearLayout android:id="@+id/llItemIcon" android:layout_width="20dip"
      android:layout_height="100dip"
      >
          <!--跳转图标-->
            <ImageView android:id="@+id/ivIcon"
            android:layout_width="12.0dip" android:layout_height="12.0dip"
            android:layout_marginRight="2dip" android:layout_marginTop="60dip"
            android:src="@drawable/into_icon" />
       </LinearLayout>
     
    </LinearLayout>

    最后就是在Activity中的实现了:

        ListView list;
        private FavourityListAdapter favouritylistadapter;
        private TPFavouriteItemFeed favouriteitemfeed;
        private List<TPFavouriteItemModel> ltFavourite;


    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.myfavourite);
            Log.d("WineStock", "TP_MyFavouriteActivity onCreate");
            if(!TPLoginUserInfo.hasLogin())
            {
                Log.d("WineStock", "please login first");
                return;
            }
            try
            {
                list = (ListView) findViewById(R.id.lvFavourite);
              
                ltFavourite = new ArrayList<TPFavouriteItemModel>();
                // 获取我的收藏的列表
                GetMyFavouriteItem();
                list.setOnItemClickListener(clickViewBtn);
              
            }
            catch(Exception e)
            {
                Log.d("WineStock", "TP_MyFavouriteActivity onCreate Error:"+e.getMessage());
            }
        }


    // 获取我的收藏夹信息
        private void GetMyFavouriteItem() {
            favouriteitemfeed = getFeed();
            if (favouriteitemfeed == null) {
                Log.d("WineStock", "访问失败...");
                return;
            } else {
                try {
                    // 获取收藏夹中的数据
                    ltFavourite = favouriteitemfeed.getAllItemListForListView();
                    // 判断收藏夹是否为空
                    if (ltFavourite.size() > 0) {
                        Log.d("WineStock", "Login my favourite");
                    } else {
                        Log.d("WineStock", "Favourite is empty");
                        return;
                    }
                    favouritylistadapter = new FavourityListAdapter(this,
                            ltFavourite, list);
                    list.setAdapter(favouritylistadapter);
                } catch (Exception e) {
                    Log.d("WineStock", "Fail to Set ListView,Error:" + e.getMessage());
                }
            }
        }

        // 获取收藏夹的xml文件
        public TPFavouriteItemFeed getFeed() {
            try {

                // 这里我们实现了本地解析,所以注掉了这个取网络数据的。
                Log.d("WineStock", "ready to get my favourite from net.");
                SAXParserFactory factory = SAXParserFactory.newInstance();
                SAXParser parser = factory.newSAXParser();
                XMLReader reader = parser.getXMLReader();
                TPFavouriteItemHandler handler = new TPFavouriteItemHandler();
                reader.setContentHandler(handler);

                String[] parameterList = new String[4];
                // 这里只是暂时测试使用
                parameterList[0] = "keyFavorites";
                parameterList[1] = "US00000065";// TPLoginUserInfo.UserIdentify;
                parameterList[2] = "10";
                parameterList[3] = "0";
                // 从webService获取数据
                String strRemoteFavouriteItemInfo = GetFavouriteItemWS(
                        Config.METHOD_GETFAVOURITEINFO, parameterList);
                if (strRemoteFavouriteItemInfo != null) {
                    InputStream inputStream = new ByteArrayInputStream(
                            strRemoteFavouriteItemInfo.getBytes());
                    InputSource is = new InputSource(inputStream);
                    reader.parse(is);
                } else {
                    Log.d("WineStock",
                            "TPFavouriteItemFeed:Get Shopping cart item error");
                }
                return handler.getCartFeed();
            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                // e.printStackTrace();
                Log.d("WineStock", "111ParserConfigurationException"
                        + e.getMessage());
            } catch (SAXException e) {
                // TODO Auto-generated catch block
                // e.printStackTrace();
                Log.d("WineStock", "222SAXException" + e.getMessage());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                // e.printStackTrace();
                Log.d("WineStock", "333IOException" + e.getMessage());
            }
            return null;
        }

        // 调用webservic来获取收藏夹的xml
        private String GetFavouriteItemWS(String methodName, String[] parameterList) {
            // 创建SoapObject对象,并指定WebService的命名空间和调用的方法名
            SoapObject request = new SoapObject(Config.NAMESPACE, methodName);
            // 调用的函数如果有参数,这里可以设置需要传递的参数 注意:第一个参数使用arg0 多个参数依次类推 arg1,arg2...
            if (parameterList != null) {
                request.addProperty("key", parameterList[0]);
                request.addProperty("userID", parameterList[1]);
                request.addProperty("dataCount", parameterList[2]);
                request.addProperty("page", parameterList[3]);
            }

            // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                    SoapEnvelope.VER11);
            // envelope.setOutputSoapObject(request);
            // 上边的一句等价于下边的这句 将SoapObject对象赋给envelope对象
            envelope.bodyOut = request;
            // 当前开发的是Java WS 这里需要不调用.net WS
            envelope.dotNet = true;

            /*
             * 这里不要使用 AndroidHttpTransport ht = new AndroidHttpTransport(URL);
             * 这是一个要过期的类
             * 创建HttpTransportSE对象。通过HttpTransportSE类的构造方法可以指定WebService的WSDL文档的URL
             */
            HttpTransportSE ht = new HttpTransportSE(Config.GETFAVOURITEINFO);
            try {
                // 请求WS
                ht.call(Config.SOAP_ACTION, envelope);
                if (envelope.getResponse() != null) {
                    // 获得WS函数返回值信息
                    // System.out.println(envelope.getResponse().toString());
                    Log.d("WineStock", "GetFavouriteItemWS Result:"
                            + envelope.getResponse().toString());
                    return envelope.getResponse().toString();
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
                Log.d("WineStock", "GetFavouriteItemWS Error:" + e.getMessage());
            }
            return null;
        }

    // 单击进入详细页面
        OnItemClickListener clickViewBtn = new OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                String goodssn = (String) ltFavourite.get(position).getProductID();
                Intent intent = new Intent(TP_MyFavouriteActivity.this,
                        ProductsInfo.class);
                Bundle bundle = new Bundle();
                bundle.putString("GoodsSn", goodssn);
                intent.putExtras(bundle);
                startActivityInFrame(intent);
            }
        };

    先只介绍这么多了,在这个画面的实现中其实还有分页和实现没有介绍,这里涉及的东西还是比较多的了。写的可能比较混乱,

    大家别见笑啊,呵呵。





  • 相关阅读:
    charles抓包实战
    linux环境安装jdk
    excel单元格数据变#号解决办法
    搭建接口自动化框架(附源码)
    dos批处理学习
    python远程操作linux服务器(获取ip,执行多条linux命令,上传文件)
    jmeter(五)创建web测试计划
    转载jmeter(四)配置元件
    JMeter(三)页面和主要测试组件
    jmeter(二)jmeter的目录解析
  • 原文地址:https://www.cnblogs.com/kevinGao/p/2482121.html
Copyright © 2011-2022 走看看