- 浏览: 149345 次
- 性别:
- 来自: 深圳
文章分类
最新评论
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);
}
};
先只介绍这么多了,在这个画面的实现中其实还有分页和实现没有介绍,这里涉及的东西还是比较多的了。写的可能比较混乱,
大家别见笑啊,呵呵。
相关推荐
本文将详细介绍如何在Android中使用SAX解析XML。 首先,我们需要了解SAX解析的基本流程。SAX解析XML的过程是基于事件的,当解析器读取XML文档时,会触发一系列的事件,如开始文档、结束文档、开始元素、结束元素等...
首先,让我们了解一下SAX解析XML的基本流程。当SAX解析器读取XML文件时,它会按照文档顺序触发一系列事件,这些事件对应于ContentHandler接口中定义的方法。以下是ContentHandler接口的一些关键方法: 1. `start...
本教程将详细讲解如何在Android中使用SAX解析XML。 首先,要使用SAX解析XML,我们需要理解其工作原理。SAX解析器会逐个读取XML文档的元素,每当遇到文档的开始、结束、文本等事件时,就会触发相应的回调方法。...
下面我们将详细讨论如何在Android中使用SAX解析XML。 首先,我们需要了解SAX解析的基本原理。SAX解析器在读取XML文档时,会触发一系列的事件,如开始文档、开始元素、结束元素、字符数据等。开发者需要定义一个...
总结,SAX解析XML在Android开发中是一个实用且高效的解决方案,尤其适用于处理大型XML文件。通过创建自定义的事件处理器,可以灵活地解析和处理XML数据,满足各种业务需求。不过,需要注意的是,由于SAX是基于事件的...
- `xmlSAXPaserDemo`可能是一个包含示例代码的Android项目,用于演示如何实际使用SAX解析XML文件。 - 项目中可能包括网络请求模块、SAX解析器处理类以及展示解析结果的UI部分。 通过以上步骤,开发者可以在...
下面详细介绍Android中使用SAX解析XML的关键步骤和相关知识点: 1. 引入库:在Android项目中,SAX解析器已经内置于`org.xml.sax`包中,无需额外导入库。 2. 创建事件处理器:你需要创建一个类来实现`...
### Android中使用SAX解析XML 1. **引入库**:在Android项目中,SAX解析器已经内置在`org.xml.sax`包中,无需额外导入库。 2. **创建ContentHandler**:创建一个实现了`org.xml.sax.ContentHandler`接口的类,重写...
下面是一个SAX解析XML的示例(有点长,因为详细注解了SAX事件处理的所有方法),SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver 和 ErrorHandler 。下面的例子可能...
本文将详细介绍如何在Android中使用SAX解析XML。 首先,理解SAX解析的基本原理。SAX解析器在读取XML文档时,会触发一系列的事件,例如开始文档、结束文档、开始元素、结束元素等。开发者需要创建一个实现了`...
在Android中使用SAX解析XML,主要涉及以下几个关键步骤: 1. **创建ContentHandler**:ContentHandler是SAX解析的核心,它定义了一系列的回调方法,用于处理XML文档的各种事件。比如`startDocument()`会在解析开始...
通过以上内容,你应该对Android中使用SAX解析XML有了深入的理解。实践过程中,可以结合具体XML文件结构和业务需求,灵活运用SAX解析器进行数据处理。同时,了解和掌握错误处理机制,以应对可能出现的异常情况,是...
**在Android中使用SAX解析XML:** 1. 引入XML解析库:在Android项目中,通常已经包含了Apache的XML解析库,无需额外添加依赖。 2. 创建事件处理器:实现`DefaultHandler`,覆盖`startElement`、`endElement`和`...
XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用于Android开发中,用于存储配置、数据交换等。...通过学习和实践,你可以掌握在Android中使用SAX解析XML的技能,提升数据处理的能力。
本教程将详细讲解如何在Android中使用SAX解析XML。 SAX解析器是事件驱动的,它逐行读取XML文档,当遇到特定的元素、属性或事件时,会触发相应的回调函数。这种方式避免了整个XML文档加载到内存中,因此对于大型XML...
以下是一个使用SAX解析XML文件的基本步骤: 1. **创建解析器**: 首先,我们需要创建一个SAX解析器实例。在Java中,这通常通过`SAXParserFactory`类完成。设置解析器属性,然后调用`newSAXParser()`方法获取`...
以下我们将逐步讲解如何在Android中使用SAX解析XML文件。 首先,我们需要创建一个`DefaultHandler`的子类,这个类是SAX解析过程中的事件处理器。在这个子类中,我们需要重写几个关键的方法,如`startElement`、`...
本文将深入讲解如何在Android中使用SAX解析XML以及如何通过SAX方式创建XML。 **1. SAX解析XML** SAX解析XML的基本流程是:创建SAXParserFactory,通过该工厂实例化SAXParser,然后设置事件处理器(ContentHandler...
在Android中,我们可以使用`DefaultHandler`作为SAX解析器的基类,创建一个继承自`DefaultHandler`的自定义处理器类,然后重写其中的方法,如`startElement`、`endElement`和`characters`,来处理XML中的元素和内容...