现在的位置: 首页 > 移动开发 > 正文

Android学习笔记—26_网络通信之资讯客户端,使用pull解析器,解析,从网络中获得的自定义xml文件

2019年09月19日 移动开发 ⁄ 共 16063字 ⁄ 字号 评论关闭

7.25_网络通信之资讯客户端
----------------------------
1.网络中一般是使用自己定义的格式比如:
  案例:酷6网的视频客户端有一个功能:“在手机上显示最新的视频资讯”,视频资讯是从        服务器获取的,数据以xml格式返回给Android客户端,然后列表显示在手机上
----------------------------------------------------
2.酷6网的视频客户端的功能解析:
  首先Adroid应用,请求路径:比如:http://www.credram.com/videonews/ListServlet
-----------------------------------
  然后这个路径会返回一个,他们自己定义的xml文件:比如:
   <video>
<item></item>
   </video>
  然后android客户端,接收到这个文件后,对这些数据进行解析,然后显示在用户手机上
---------------------------------------------------------------------------
3.那么这种情况下就需要开发web应用,和android应用,两个应用:
-----------------------------------------------------------------
4.注意:在android应用中需要将从web中得到的数据解析成以下格式:
  界面显示:
  xxxxxxxxxxxxxx(视频的标题)    时长:90分钟
------------------------------
5.下面是通过网络,获取自定义的xml文件数据,然后解析,然后显示在手机上
------------------------------------------------
6.以下是网络通信之资讯客户端的所有源码:
-------------------------
a.首先要创建web项目:VideoNews
-----------------------------------
b.写一个servlet,生成xml文件
--------------------------
/VideoNews/src/com/credram/servlet/ListServlet.java
package com.credram.servlet;

import java.io.IOException;
import java.util.List;

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

import com.credream.entity.News;
import com.credream.service.VideoNewsService;
import com.credream.service.impl.VideoNewsServiceImpl;

/**
 * Servlet implementation class ListServlet
 */
public class ListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
       
 

private VideoNewsService service=new VideoNewsServiceImpl();
    public ListServlet() {
 
       
    }

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
List<News> videos=service.getLastNews();
request.setAttribute("videos", videos);
request.getRequestDispatcher("/WEB-INF/page/videosnews.jsp").forward(request, response);
}

}
-------------------------------------------------------------
c./VideoNews/src/com/credream/entity/News.java
package com.credream.entity;

public class News
{
private Integer id;
private String title;
private Integer timelength;

public News()
{
 
}
public News(Integer id, String title, Integer timelength)
{
super();
this.id = id;
this.title = title;
this.timelength = timelength;
}
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public Integer getTimelength()
{
return timelength;
}
public void setTimelength(Integer timelength)
{
this.timelength = timelength;
}

}
--------------------------------------------------------------
d./VideoNews/src/com/credream/service/VideoNewsService.java
package com.credream.service;

import java.util.List;

import com.credream.entity.News;

public interface VideoNewsService
{
/**
 * 获取最新视频资讯
 * @return
 */
public List<News> getLastNews();

}
-------------------------------------------------------
e./VideoNews/src/com/credream/service/impl/VideoNewsServiceImpl.java
package com.credream.service.impl;

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

import com.credream.entity.News;
import com.credream.service.VideoNewsService;

public class VideoNewsServiceImpl implements VideoNewsService
{
/* (non-Javadoc)
 * @see com.credream.service.impl.VideoNewsService#getLastNews()
 */
public List<News> getLastNews(){
List<News> newses= new ArrayList<News>();
newses.add(new News(35,"喜洋洋喜洋洋",90));
newses.add(new News(20,"李德伟大侠",15));
newses.add(new News(50,"马长海和莉莉",16));
return newses;


}
--------------------------------------------------------
f./VideoNews/WebContent/WEB-INF/page/videosnews.jsp
<%@ page language="java" contentType="text/xml; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><?xml version="1.0" 

encoding="UTF-8"?>
<videonews><c:forEach items="${videos}" var="video">
<news id="${video.id}">
<title>${video.title}</title>
<timelength>${video.timelength}</timelength>
</news></c:forEach>
</videonews>
-------------------------------------------------------
g./VideoNews/WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>VideoNews</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>ListServlet</display-name>
    <servlet-name>ListServlet</servlet-name>
    <servlet-class>com.credram.servlet.ListServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ListServlet</servlet-name>
    <url-pattern>/ListServlet</url-pattern>
  </servlet-mapping>
</web-app>
---------------------------------------------------------
1.注意在部署android应用的时候报错:
----------------------------------------
Please ensure that adb is correctly located at问题解决 
----------------------------------------------------------
a.第一种解决方法:
运行android程序控制台输出

    [2012-07-18 16:18:26 - ] The connection to adb is down, and a severe error has occured.
    [2012-07-18 16:18:26 - ] You must restart adb and Eclipse.
    [2012-07-18 16:18:26 - ] Please ensure that adb is correctly located at 'D:\java\sdk\platform-tools\adb.exe' and can be executed.

解决问题:
百度google大家多说的是任务管理器 kill掉adb 或者重启adb server,但我任务管理器就没有adb ,猜测是某个程序占用了adb端口。于是按此思路查找。

5037为adb默认端口 查看该端口情况如下:

       netstat -aon|findstr "5037"

      TCP    127.0.0.1:5037         0.0.0.0:0              LISTENING       6540

发现6540占用了 5037端口,继续查看6540的task,发现是wandoujia  .如下所示

        tasklist|findstr "6540"

        wandoujia_daemon.exe          6540 Console                    1      4,276 K

接下来问题就好解决了,在任务管理器kill掉wandoujia_daemon.exe ,运行android程序,ok .
----------------------
注意:打开任务管理器,点击菜单上的选择列,可以显示pid号
---------------------------------------------------------------------
b.
--------------------------------------------------
2.[2013-03-20 22:28:19 - News] ActivityManager: Warning: Activity not started, its current task has been brought to the front
-----------------------------------------------------------
3.运行程序时提出了这个一个警告:Activity not started, its current task has been brought to the front 。

解答:因为你的模拟器中还有东西在运行,也就是你要运行的activity已经有一个在模拟器中运行了。
不要以认为模拟器退出到桌面了就没有东西在跑了。在你调试的时候异常关闭的程序有可能就有activity在运行。
解决方法project->clean。
----------------------------------
在运行Android程序时,有时提示如下,表面程序无法运行。 
ActivityManager: Warning: Activity not started, its current task has been brought to the front
if ($ != jQuery) { $ = jQuery.noConflict(); } var isLogined = false; var cb_blogId = 41091; var cb_entryId = 2015362; var cb_blogApp = "cyb350623"; var cb_blogUserGuid 

= "d449420b-63cf-dd11-9e4d-001cf0cd104b"; var cb_entryCreatedDate = '2011/4/13 22:15:00'; 
这个不是Android平台的Bug,而是Android本身就是这样一种处理机制。
我们在Android平台下,通过返回按钮,或者程序本身的退出操作,去结束一个进程的时候,实际上Android虚拟机未必会将这个进程真正的结束掉,在内存允许的情况下,这个程序会以缓存

的形式存在Android虚拟机中。只有在内存不足的情况下时,Android系统会清理长时间不被激活的任务,以为其他程序提供内存。
Android这样做,是为了你下一次更加快速的启动这个程序。
所以,出现这种情况,是在你的程序没有发生任何变化,并且内存足够的情况下,会将上一次执行的程序,从缓存Cached状态直接放置到任务栈的顶端,则你的程序又可以继续执行了。
------------------------------------------------------
4.03-22 21:37:26.257: W/System.err(633): at java.net.Socket.connect(Socket.java:1055)

03-22 21:37:26.232: W/System.err(633): java.net.ConnectException: localhost/127.0.0.1:6118 - Connection refused

注意:这里提示不可以用localhost/127.0.0.1:6118,这种地址要用:192.168.1.110这样的局域网地址;
-----------------------------------------------------------------------------------------------
5.03-22 21:42:10.091: W/System.err(661): java.lang.IllegalStateException: End of document.
------------------------------------------------------------------------------------
a.
先看下这个xml文件的内容:
  <?xml version="1.0" encoding="UTF-8" ?> 
<videonews>
 <news id="35">
  <title>喜洋洋喜洋洋</title> 
  <timelength>90</timelength> 
  </news>
 <news id="20">
  <title>李德伟大侠</title> 
  <timelength>15</timelength> 
  </news>
 <news id="50">
  <title>马长海和莉莉</title> 
  <timelength>16</timelength> 
  </news>
  </videonews>
------------------------------------------------------------------------------------------
 报了这个错误,这个地方是由于多加了一个:
   private static  List<News> parseXML(InputStream inStream)throws Exception
{
List<News> newses=new ArrayList<News>();
News news=null;
XmlPullParser parser=Xml.newPullParser();
parser.setInput(inStream, "UTF-8");
int event=parser.getEventType();
while(event!=XmlPullParser.END_DOCUMENT){
//event=parser.next();//原因是这个地方原来没有被注释掉,这样的话,他会一个节点一个节点的读那么第一个节点读出来的就是:<videonews>这样的话,下面的代码就 

               //没法执行了,
                //所以就报了下面的错误:private static  List<News> parseXML(InputStream inStream)throws Exception
{
List<News> newses=new ArrayList<News>();
News news=null;
XmlPullParser parser=Xml.newPullParser();
parser.setInput(inStream, "UTF-8");
int event=parser.getEventType();
while(event!=XmlPullParser.END_DOCUMENT){
//event=parser.next();
switch (event)
{
case XmlPullParser.START_TAG://如果不用event=parser.next(),而直接判断的话,那么解析是从<news 开始的,这样才是正确的.
if("news".equals(parser.getName())){
int id= new Integer(parser.getAttributeValue(0));
news=new News();
news.setId(id);
}else if("title".equals(parser.getName())){
news.setTitle(parser.nextText());
}else if("timelength".equals(parser.getName())){
news.setTimelength(new Integer(parser.nextText()));
}
break;
case XmlPullParser.END_TAG:
if("news".equals(parser.getName())){
newses.add(news);
news=null;
}
break;
}
event=parser.next();
}

return newses;
}
}
switch (event)
{
case XmlPullParser.START_TAG:
if("news".equals(parser.getName())){
int id= new Integer(parser.getAttributeValue(0));
news=new News();
news.setId(id);
}else if("title".equals(parser.getName())){
news.setTitle(parser.nextText());
}else if("timelength".equals(parser.getName())){
news.setTimelength(new Integer(parser.nextText()));
}
break;
case XmlPullParser.END_TAG:
if("news".equals(parser.getName())){
newses.add(news);
news=null;
}
break;
}
event=parser.next();
}

return newses;
}
-------------------------------------------------------------
1.以下是这个项目的Android客户端的所有代码:
------------------------------------------------
/GetNetNews/src/com/credream/entity/News.java
package com.credream.entity;
public class News
{
private Integer id;
private String title;
private Integer timelength;public News()
{
 
}
public News(Integer id, String title, Integer timelength)
{
super();
this.id = id;
this.title = title;
this.timelength = timelength;
}
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public Integer getTimelength()
{
return timelength;
}
public void setTimelength(Integer timelength)
{
this.timelength = timelength;
}
}
------------------------------------------------------
b./GetNetNews/src/com/credream/service/VideoNewsService.java
package com.credream.service;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;

import android.util.Xml;

import com.credream.entity.News;

public class VideoNewsService
{
public static  List<News> getLastNews()throws Exception{
String path="http://192.168.1.110:6118/VideoNews/ListServlet";
URL url=new URL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode()==200){
InputStream inStream=conn.getInputStream();
return parseXML(inStream);
}
return null;
}
/**
 * 解析服务器返回的xml数据
 * 
 * 
 <?xml version="1.0" encoding="UTF-8" ?> 
<videonews>
 <news id="35">
  <title>喜洋洋喜洋洋</title> 
  <timelength>90</timelength> 
  </news>
 <news id="20">
  <title>李德伟大侠</title> 
  <timelength>15</timelength> 
  </news>
 <news id="50">
  <title>马长海和莉莉</title> 
  <timelength>16</timelength> 
  </news>
  </videonews>
 * @param inStream
 * @return
 */
private static  List<News> parseXML(InputStream inStream)throws Exception
{
List<News> newses=new ArrayList<News>();
News news=null;
XmlPullParser parser=Xml.newPullParser();
parser.setInput(inStream, "UTF-8");
int event=parser.getEventType();
while(event!=XmlPullParser.END_DOCUMENT){
//event=parser.next();
switch (event)
{
case XmlPullParser.START_TAG:
if("news".equals(parser.getName())){
int id= new Integer(parser.getAttributeValue(0));
news=new News();
news.setId(id);
}else if("title".equals(parser.getName())){
news.setTitle(parser.nextText());
}else if("timelength".equals(parser.getName())){
news.setTimelength(new Integer(parser.nextText()));
}
break;
case XmlPullParser.END_TAG:
if("news".equals(parser.getName())){
newses.add(news);
news=null;
}
break;
}
event=parser.next();
}

return newses;
}

}
-----------------------------------------------------------------------------------------
c./GetNetNews/src/com/credream/video/NewsActivity.java
 package com.credream.video;

import java.util.*;

import com.credream.entity.News;

import com.credream.service.VideoNewsService;

import android.app.Activity;

import android.os.Bundle;

import android.widget.ListView;

import android.widget.SimpleAdapter;

public class NewsActivity extends Activity
{

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

ListView listView = (ListView) this.findViewById(R.id.listView);

try
{

List<News> videos = VideoNewsService.getLastNews();

List<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();

for (News news : videos)
{

HashMap<String, Object> item = new HashMap<String, Object>();

item.put("id", news.getId());

item.put("title", news.getTitle());

/**

 * item.put("timelength","时间:"+news.getTimelength()+ "分钟");

* //注意这里的汉字,时间,分钟是从string.xml文件中读取的

 * getResources()(从资源文件中得到string

 * .xml文件).getString(R.string.timelength)

 * (从string.xml文件中得到timelength为id的字符串)

 */

item.put(
"timelength",
getResources().getString(R.string.timelength)
+ news.getTimelength()
+ getResources().getString(R.string.min));

data.add(item);

}

// 创建适配器,并且赋值给显示控件listview

SimpleAdapter adapter = new SimpleAdapter(this, data,
R.layout.item, new String[]
{ "title", "timelength" }, new int[]
{ R.id.title, 

R.id.timelength });

listView.setAdapter(adapter);


} catch (Exception e)
{

e.printStackTrace();

}

}
}
-------------------------------------------------------------------------------------------------------------------------------------
d./GetNetNews/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.credream.video"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".NewsActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 <!--访问网络权限-->
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>
------------------------------------------------------------------------------
e./GetNetNews/res/layout/item.xml
 <?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="wrap_content"
    android:orientation="horizontal" >
    <TextView
        android:layout_width="230dp"
    android:layout_height="wrap_content"
android:id="@+id/title"    
         />
   <TextView
        android:layout_width="fill_parent"
    android:layout_height="wrap_content"
android:id="@+id/timelength"    
         />
</LinearLayout>
---------------------------------------------------
f./GetNetNews/res/layout/main.xml
<?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"
    android:orientation="vertical" >

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/listView" />

</LinearLayout>
----------------------------------------------------
g./GetNetNews/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="hello">Hello World, NewsActivity!</string>
    <string name="app_name">视频资讯</string>
    <string name="timelength">时长:</string>
    <string name="min">分钟</string>
</resources>
----------------------------------------------------------------

抱歉!评论已关闭.