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>
----------------------------------------------------------------