Android之异步任务AsyncTask解析XML数据

一、服务器端 生成XML数据

①新建Web工程Web_AsyncTask_Xml

空白处右键->new->other->Web->Dynamic Web Project

②创建XML文件citys.xml

工程下面的WebContent右键->New ->other->XML->XMLFile->citys.xml,把新建的citys.xml文件拷贝一份放到包com.city.action下面,产生数据源,也就是说我在这个包里面把这个XML文件读出来,变成一个字符串而不是访问一个文件。(假设用手机访问天气预报,如果现在天气预报返回的格式是XML, 当然这些数据是来自数据库,我们根本没有必要让这些数据生成一个文件,让用户再读这个文件。做练习是这样的,但是,实际开发开发并不是这样的, 只需要在数据库中读取数据,直接把这些数据变成字符串,这样就少了一次Io读写。)

<?xml version="1.0" encoding="UTF-8"?>
<citys>
    <city>
        <name>Beijing</name>
    </city>
    <city>
        <name>上海</name>
    </city>
    <city>
        <name>广州</name>
    </city>
    <city>
        <name>深圳</name>
    </city>
</citys>

③在包com.city.action下面创建CityAction.java,接着创建CityDataSource.java(仿照上一篇Android之异步任务AsyncTask解析Json数据

CityAction.java

package com.city.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONSerializer;

/**
 * Servlet implementation class CityAction
 */
@WebServlet("/CityAction")
public class CityAction extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * Default constructor. 
     */
    public CityAction() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		request.setCharacterEncoding("utf-8");
		PrintWriter writer=response.getWriter();
		String type=request.getParameter("type");
		if(type.equals("xml")){
			String xmlString=CityDataSource.getCityListXML();//取出xml
			writer.println(xmlString);
		}
		
		writer.flush();
		writer.close();
	}

}
CityDataSource.java

package com.city.action;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

public class CityDataSource {

	public CityDataSource() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * 假设用手机访问天气预报,如果现在天气预报返回的格式是XML, 当然这些数据是来自数据库,我们根本没有必要让这些数据生成一个文件,
	 * 让用户再读这个文件。做练习是这样的,但是,实际开发开发并不是这样的, 只需要在数据库中读取数据,直接把这些数据变成字符串,这样就少了一次Io读写。
	 * 
	 * 使用InputStream去读,把XML变成一个字符串
	 * 
	 * 
	 * 服务器端的工作:把把字节流读取出来,放到StringBuilder中,并且什么都没解析,直接把结果通过一个字符串返回给客户端
	 * @return
	 */
	public static String getCityListXML() {
		InputStream inputStream = CityDataSource.class.getClassLoader()
				.getResourceAsStream("com/city/action/citys.xml");// 通过类的反射,得到一个类的加载器,然后用这个类的加载器去加载一个文件,这个文件就是一个流
		
		Reader reader=new InputStreamReader(inputStream,Charset.forName("utf-8"));//解决乱码
		BufferedReader bufferedReader=new BufferedReader(reader);//把一个流文件转换成字符串,把字节流转成字符流
		String value="";
		StringBuilder builder=new StringBuilder();
		try {
			while((value=bufferedReader.readLine())!=null){
				builder.append(value);
			}
			//System.out.println(builder.toString());
			//return new String(builder.toString().getBytes("iso8859-1"),"utf-8");//如果有乱码问题则加上这句话,在getCityListXML方法返回null
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(bufferedReader!=null){
				try {
					bufferedReader.close();
				} catch (Exception e2) {
					// TODO Auto-generated catch block
					e2.printStackTrace();
				}
			}
		}
		//return list;
		return builder.toString();
		//return null;//如果有乱码,则加上getBytes("iso8859-1"),"utf-8")后再加上这句
		
	}

	public static void main(String[] args) {
		getCityListXML();
		
	}
}

在地址栏输入http://192.168.1.100:8080/Web_AsyncTask_Xml/CityAction?type=xml显示如下


二、手机客户端

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.android_asynctask_xml.MainActivity" >

	 <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="31dp"
        android:layout_marginTop="102dp"
        android:textSize="20sp"
        android:text="所属城市:" />

    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/textView1"
        android:layout_marginLeft="14dp"
        android:layout_toRightOf="@+id/textView1" />
</RelativeLayout>

①添加访问网络权限

②新建包com.example.android_asynctask_xml.http,在包里面创建HttpUtils.java工具类

package com.example.android_asynctask_xml.http;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class HttpUtils {

	public HttpUtils() {
		// TODO Auto-generated constructor stub
	}
	
	/**
	 * 
	 * @param path  获取指定路径的json信息
	 * @param encoding  指定编码格式
	 * @return
	 */
	public static String sendPostMethod(String path,String encoding){
		String result="";
		HttpClient httpClient=new DefaultHttpClient();
		try {
			HttpPost post=new HttpPost(path);
			HttpResponse response=httpClient.execute(post);
			if(response.getStatusLine().getStatusCode()==200){
				result=EntityUtils.toString(response.getEntity(), encoding);
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			httpClient.getConnectionManager().shutdown();//关闭连接
		}
		return result;
		
	}
}

新建包com.example.android_asynctask_xml.Entity,在包里面创建实体类City.java

package com.example.android_asynctask_xml.Entity;

public class City {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

④新建包com.example.android_asynctask_xml.xml,在包里面创建工具类XMLTools.java

package com.example.android_asynctask_xml.xml;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import com.example.android_asynctask_xml.Entity.City;

public class XMLTools {

	public XMLTools() {
		// TODO Auto-generated constructor stub
	}
	
	/**
	 * 
	 * 解析XML文件
	 * 利用XML解析工厂XmlPullParserFactory,通过工厂new一个解析器newPullParser
	 * 
	 * 在Mainactivity.java中调用
	 * @param xmlString
	 * @return
	 */
	public static List<City> parseXML(String xmlString){
		List<City> list=null;
		City city=null;
		try {
			XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
			XmlPullParser parser=factory.newPullParser();
			parser.setInput(new StringReader(xmlString));
			int eventType=parser.getEventType();
			while(eventType!=XmlPullParser.END_DOCUMENT){
				switch (eventType) {
				case XmlPullParser.START_DOCUMENT:
					list=new ArrayList<City>();
					break;
				case XmlPullParser.START_TAG:
					if("city".equals(parser.getName())){
						city=new City();
					}else if("name".equals(parser.getName())){
						String name=parser.nextText();
						city.setName(name);
					}
					break;
				case XmlPullParser.END_TAG:
					if("city".equals(parser.getName())){
						list.add(city);
						city=null;
					}
					break;
				}
				eventType=parser.next();
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		return list;
	}
}
⑤在包com.example.android_asynctask_xml里面MainActivity.java

package com.example.android_asynctask_xml;

import java.util.ArrayList;
import java.util.List;

import com.example.android_asynctask_xml.Entity.City;
import com.example.android_asynctask_xml.http.HttpUtils;
import com.example.android_asynctask_xml.xml.XMLTools;

import android.support.v7.app.ActionBarActivity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

public class MainActivity extends ActionBarActivity {

	private final String TAG="MainActivity";
	private Spinner spinner1;
	private final String CITY_PATH="http://192.168.1.100:8080/Web_AsyncTask_Xml/CityAction?type=xml";
	private ArrayAdapter<String> adapter;
	private ProgressDialog dialog;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		spinner1=(Spinner) this.findViewById(R.id.spinner1);//加载Spinner控件
		//adapter=new ArrayAdapter<String>(context, resource, textViewResourceId);
		//spinner1.setAdapter(adapter);//这句话执行完之后,数据就已经有了,所以这行代码应该在另外一个线程中实现,然后再更新UI
		dialog=new ProgressDialog(MainActivity.this);
		dialog.setTitle("提示");
		dialog.setMessage("正在加载...");
		new MyTask().execute(CITY_PATH);//执行异步任务
		
	}

	class MyTask extends AsyncTask<String, Void, List<City>>{

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			dialog.show();
		}
		
		@Override
		protected void onPostExecute(List<City> result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			List<String> list=new ArrayList<String>();
			for(int i=0;i<result.size();i++){
				list.add(result.get(i).getName());
			}
			adapter=new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, list);//构建适配器
			spinner1.setAdapter(adapter);
			dialog.dismiss();
		}
		
		/**
		 * 注意:在做Android开发过程中HttpUtils和JsonTools工具类是必须要有的
		 * 在一个项目中json数据格式有可能有四到五种,所以工具类里的方法要有四到五个方法来解析
		 */
		@Override
		protected List<City> doInBackground(String... params) {
			// TODO Auto-generated method stub
			List<City> list=null;
			String xmlString=HttpUtils.sendPostMethod(params[0], "utf-8");
			
			//Log.i(TAG, "--->>"+xmlString);//验证能否将xml数据取到本地
			list=XMLTools.parseXML(xmlString);
			//System.out.println("--list--"+list);
			return list;
		}
		//List<String>这个结果表示json解析之后的结果,结果会很快塞到适配器当中
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}
具体步骤可以借鉴上一篇 Android之异步任务AsyncTask解析Json数据

运行效果图


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值