小菜鸟我使用的是android studio
Eclipse下libs里添加org.apache.http.legacy.jar
网络请求是已经被谷歌抛弃的httpclient,当然也可以使用Google比较喜欢的httpurlconnection.以下我是以httoclient为例,
首先是 在项目中的build.app中设置添加如下在代码useLibrary 'org.apache.http.legacy'
在android { compileSdkVersion 25 buildToolsVersion "25.0.3" defaultConfig { applicationId "com.example.wk620xml.wk620xml" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } useLibrary 'org.apache.http.legacy' }有可能会报错。可以如下操作对于xml解析需要我们自己建小型服务器 我们可以使用Apache服务器安装包,当然也可以有其他选择,下载地址:http://httpd.apache.org/download.cgiHttpClient虽然已经被Google抛弃,但是有限项目依然依赖这些库,还得用。我把Httpclient的所有库导入项目后,会产生如下错误。
Error:duplicate files during packaging of APK F:\Downloads\MyApplication7\app\build\outputs\apk\app-debug-unaligned.apk
Path in archive: META-INF/DEPENDENCIES
Origin 1: F:\Downloads\MyApplication7\app\libs\httpclient-4.5.2.jar
Origin 2: F:\Downloads\MyApplication7\app\libs\httpcore-4.4.4.jar
经过查找可以在文件中加入以下代码消除这个问题。
- packagingOptions {
- exclude 'META-INF/DEPENDENCIES'
- exclude 'META-INF/NOTICE'
- exclude 'META-INF/LICENSE'
- exclude 'META-INF/LICENSE.txt'
- exclude 'META-INF/NOTICE.txt'
- exclude 'META-INF/ASL2.0'
- exclude 'META-INF/notice.txt'
- }
安装方法是一直点击下一步。会提示输入自己的域名,这个可以随便填,到选择安装路径的时候,可以默认路径,安装完成后可以在浏览器地址栏中输入127.0.0.1,可以弹出页面说明我们的服务器已经启动成功,接着进入到Apachede安装目录下,小菜鸟是在c:\Apache\Apache2\htdocs目录下,我们可以新建一个文件夹get_date,编辑文件
编辑代码如下:
<apps> <app> <id>1</id> <name>google11111</name> <vesion>1.0</vesion> </app> <app> <id>2</id> <name>google22222</name> <vesion>2.0</vesion> </app> <app> <id>3</id> <name>google333333</name> <vesion>3.0</vesion> </app> </apps>
服务器的准备工作结束,当然可以使用android studio中的自带布局那块的属性,直接编辑一个本地服务器进行解析
// TODO: 2017-06-20 pull解析 吴凯 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //这是pull解析 private void sendRequestWithHttpClient() { new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); //指定访问的服务器地址是电脑本机 HttpGet httpGet = new HttpGet("http://10.2.2/get_date.xml"); HttpResponse httpResponse = httpClient.execute(httpGet); //因为http请求的响应时间确定是否响应成功 if (httpResponse.getStatusLine().getStatusCode() == 200) { //请求和相应成功 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity, "utf-8"); parseXMLwithPull(response); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } private void parseXMLwithPull(String xml) { try { //XmlPullParserFactory首先是获取实例 XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); //利用实例调用setinput将数据写进去 XmlPullParser xmlPullParser = factory.newPullParser(); xmlPullParser.setInput(new StringReader(xml)); //通过调用此方法得到当前解析事件 int eventType = xmlPullParser.getEventType(); String id = ""; String name = ""; String version = ""; while (eventType != xmlPullParser.END_DOCUMENT) { String nodename = xmlPullParser.getName(); switch (eventType) { case XmlPullParser.START_TAG: { //开始解析某个节点 if ("id".equals(nodename)) { try { id = xmlPullParser.nextText(); } catch (IOException e) { e.printStackTrace(); } } else if ("name".equals(nodename)) { try { name = xmlPullParser.nextText(); } catch (IOException e) { e.printStackTrace(); } } else if ("version".equals(nodename)) { try { version = xmlPullParser.nextText(); } catch (IOException e) { e.printStackTrace(); } } break; } //完成解析某个节点 case XmlPullParser.END_TAG: { if ("app".equals(nodename)) { Log.e("mainactivity", "id====" + id); Log.e("mainactivity", "name===" + name); Log.e("mainactivity", "version===" + version); } break; } default: break; } try { eventType = xmlPullParser.next(); } catch (IOException e) { e.printStackTrace(); } } } catch (XmlPullParserException e) { e.printStackTrace(); } } } -------------------------------------------------------------------------------- 以上是pull解析 接下来写一个简单的sax解析 首先需要写一个方法继承defaulthandler// TODO: 2017-06-20 sax解析 吴凯 public class MyHandler extends DefaultHandler { private String nodename; private StringBuilder id; private StringBuilder name; private StringBuilder version; //xml解析时候会调用 @Override public void startDocument() throws SAXException { id = new StringBuilder(); name = new StringBuilder(); version = new StringBuilder(); // super.startDocument(); } //xml开始解析某个节点时候会调用 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //记录当前的节点名 nodename = localName; // super.startElement(uri, localName, qName, attributes); } //xml获取某个节点时候会调用 @Override public void characters(char[] ch, int start, int length) throws SAXException { //根据当前节点名判断将内容添加到哪一个stringbuilder对象中 if ("id".equals(nodename)) { id.append(ch, start, length); } else if ("name".equals(nodename)) { name.append(ch, start, length); } else if ("version".equals(nodename)) { version.append(ch, start, length); } // super.characters(ch, start, length); } //xml完成某个节点时候调用 @Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("app".equals(localName)) { Log.e("myhander", "id====" + id.toString().trim()); Log.e("myhander", "name===" + name.toString().trim()); Log.e("myhander", "version===" + version.toString().trim()); //最后将stringbuidler清空掉 id.setLength(0); name.setLength(0); version.setLength(0); } // super.endElement(uri, localName, qName); } //xml解析完成整个节点时候调用 @Override public void endDocument() throws SAXException { super.endDocument(); } }=========================
在mainactivity操作// TODO: 2017-06-20 pull解析 吴凯 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //这是pull解析 private void sendRequestWithHttpClient() { new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); //指定访问的服务器地址是电脑本机 HttpGet httpGet = new HttpGet("http://10.2.2/get_date.xml"); HttpResponse httpResponse = httpClient.execute(httpGet); //因为http请求的响应时间确定是否响应成功 if (httpResponse.getStatusLine().getStatusCode() == 200) { //请求和相应成功 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity, "utf-8"); parsexmlsax(response); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } private void parsexmlsax(String xml) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); XMLReader xmlreader = factory.newSAXParser().getXMLReader(); MyHandler handler = new MyHandler(); //将myhandler实例设置进入xmlreader xmlreader.setContentHandler(handler); //开始执行解析 try { xmlreader.parse(new InputSource(new StringReader(xml))); } catch (IOException e) { e.printStackTrace(); } } catch (SAXException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } } } //总结最后分析下xml解析dom,pull,sax三种的区别,以及优缺点1、DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的,把整个xml数据加载进去
2、SAX是基于事件驱动的。、边加载边解析
3、 SAX方式是基于事件驱动的。、PULL方式读xml回调方法返回的是数字。
边加载边解析
读取到xml的声明返回 START_DOCUMENT;
读取到xml的结束返回 END_DOCUMENT ;
读取到xml的开始标签返回 START_TAG
读取到xml的结束标签返回 END_TAG
读取到xml的文本返回 TEXT