Android之异步任务AsyncTask解析XML数据
2015-12-14 14:45
585 查看
一、服务器端 生成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读写。)
③在包com.city.action下面创建CityAction.java,接着创建CityDataSource.java(仿照上一篇Android之异步任务AsyncTask解析Json数据)
CityAction.java
在地址栏输入http://192.168.1.100:8080/Web_AsyncTask_Xml/CityAction?type=xml显示如下
二、手机客户端
activity_main.xml
①添加访问网络权限
②新建包com.example.android_asynctask_xml.http,在包里面创建HttpUtils.java工具类
③新建包com.example.android_asynctask_xml.Entity,在包里面创建实体类City.java
④新建包com.example.android_asynctask_xml.xml,在包里面创建工具类XMLTools.java
运行效果图
①新建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数据
运行效果图
相关文章推荐
- Android4.4以上系统选择将第三方短信应用设置为默认短信应用方法
- 【android_温故知新】对话框
- Android中的ANR异常
- Android研究院之自定义view
- android控件显示与隐藏的时候的动画效果
- Android各个资源文件
- Android学习笔记(二) listview与adapter用法
- Android四种存储方式
- 关于使用梆梆加固后,适配android5.0系统与64位机型的问题
- Android编程基于Contacts读取联系人的方法(附demo源码)
- Android目录结构简介
- Android应用开发自定义图片剪辑头像设置
- Android View和ViewGroup的关系
- 【动态加载】Android动态加载:简单加载模式
- Android开发必备知识:我和Gradle有个约会
- Android中的RectF类和PointF类
- Android使用Sencha完成APK局部更新
- Android开机广播android.intent.action.BOOT_COMPLETED
- Android NotificationManager
- Android图片、文字国际化