Android 网络学习之获取server文本文件
上次我们学习怎样从网络上获取一张图片,今天我们学习怎样从网络上获取文本文件。以XML文件为样例。
由于XML文件在实际开发中最为常见。
我们以以下图片为样例学习怎样从网络上获取XML文件
我们的xml文件为:
<? xml version="1.0" encoding="UTF-8" ?>
<newslist>
<news>
<title>9月起办理手机卡需实名认证</title>
<detail>方案要求,从2015年2月1日起,基础电信企业和虚拟运营商的各类营销渠道在为用户办理电话入网手续时,停止人工录入方式,改用专用移动应用程序</detail>
<comment>15687</comment>
<image>http://192.168.1.100:8080/images/6.jpg</image>
</news>
<news>
<title>富士康50亿美元印度建厂 中国制造成本直逼美国</title>
<detail>中国制造”和“印度制造”正展开新一轮的竞争与合作关系。全球最大的代工企业、中国台湾的富士康8月8日在印度签约。它到印度投资设厂的计划变为现实</detail>
<comment>16359</comment>
<image>http://192.168.1.100:8080/images/7.jpg</image>
</news>
<news>
<title>刘强东也学乔布斯 增加“1元年薪”俱乐部</title>
<detail>8月8日,京东集团董事长兼CEO刘强东与奶茶妹妹的结婚证照片在朋友圈里刷屏了。可就在前一天,刘强东还将自己未来十年的年薪降至1元</detail>
<comment>14112</comment>
<image>http://192.168.1.100:8080/images/7.jpg</image>
</news>
后面的太长省略了。
既然我们要将xml文件里的内容显示到界面上,那必须先要拿到xml文件里的内容。
1: 从网络上获取XML文件的内容
开启一个子线程从网络上获取server的数据
public void getNewsInfo()
{
//在子线程中获取server的数据
Thread thread = new Thread(){
@Override
public void run() {
//1:确定地址
String path = "http://192.168.1.123:8080/news.xml";
try {
URL url = new URL(path);
//建立连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式
conn.setRequestMethod("GET");
//设置请求超时时间
conn.setConnectTimeout(5000);
//设置读取超时时间
conn.setReadTimeout(5000);
//推断是否获取成功
if(conn.getResponseCode() == 200)
{
//获得输入流
InputStream is = conn.getInputStream();
//解析输入流中的数据
parseXmlInfo(is);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}; //启动线程
thread.start();
}
获取到server给的数据,然后解析XML文件。解析XML文件我们使用的是PULL解析器
public void parseXmlInfo(InputStream is)
{
/*我们用pull解析器解析xml文件*/ //1.先拿到pull解析器
XmlPullParser xParser = Xml.newPullParser(); try { xParser.setInput(is, "utf-8");
//获取事件的类型
int eventType = xParser.getEventType();
News news = null;
while(eventType != XmlPullParser.END_DOCUMENT)
{
switch (eventType) {
case XmlPullParser.START_TAG:
//当事件的開始类型newslist。代表的是xml文件的数据開始
if("newslist".equals(xParser.getName()))
{
//这时候我们就new出来一个list,用于保存数据
newList = new ArrayList<News>();
}//当事件类型是news。说明是一条新闻
else if ("news".equals(xParser.getName())) {
//new出一个news的对象
news = new News();
}
else if ("detail".equals(xParser.getName())) {
String detail = xParser.nextText();
news.setDetail(detail);
}
else if ("title".equals(xParser.getName())) {
String title = xParser.nextText();
news.setTitle(title);
}
else if ("comment".equals(xParser.getName())) {
String comment = xParser.nextText();
news.setComment(comment);
}
else if ("image".equals(xParser.getName())) {
String image = xParser.nextText();
news.setImage(image);
}
break;
case XmlPullParser.END_TAG:
//当结束时间是news时。说明一条news已经解析完毕,而且增加到集合中
if("news".equals(xParser.getName()))
{
newList.add(news);
}
break;
} eventType = xParser.next();
} //打印
for (News n : newList) {
System.out.println(n.toString());
} } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
打印为:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
能够看到我们是从server取到了数据,而且数据是正确的。
2: 既然能够正确的取到数据,那我们就将数据显示到界面上,既然要显示。 那就的用listview。既然要用listview。那就必须为listview的每个添加一个布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context="${relativePackage}.${activityClass}" > <ImageView
android:id="@+id/iv"
android:layout_width="90dp"
android:layout_height="70dp"
android:src="@drawable/ic_launcher"
android:layout_centerVertical="true"
/>
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="大标题"
android:textSize="20sp"
android:layout_toRightOf="@id/iv"
android:singleLine="true"
/> <TextView
android:id="@+id/tv_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是新闻的具体信息"
android:textSize="15sp"
android:textColor="@android:color/darker_gray"
android:lines="2"
android:layout_toRightOf="@id/iv"
android:layout_below="@id/tv_title"
/> <TextView
android:id="@+id/tv_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="19999"
android:textColor="#FF0000"
android:layout_alignParentRight="true"
android:layout_below="@id/tv_detail"
/>
</RelativeLayout>
我们找到listview。然后设置Adapter就可以
ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new MyAdapter());
class MyAdapter extends BaseAdapter
{ @Override
public int getCount() {
// TODO Auto-generated method stub
return newList.size();
} @Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
//取到一条新闻
News news = newList.get(position);
//找到一个view对象
View v = View.inflate(MainActivity.this, R.layout.item_listview, null); //依据ID找到控件
TextView tv_title = (TextView) v.findViewById(R.id.tv_title);
TextView tv_detail = (TextView) v.findViewById(R.id.tv_detail);
TextView tv_comment = (TextView) v.findViewById(R.id.tv_comment);
ImageView siv = (ImageView)v.findViewById(R.id.iv); //设置数据
tv_title.setText(news.getTitle());
tv_detail.setText(news.getDetail());
tv_comment.setText(news.getComment() + "条评论");
siv.setImageResource(R.drawable.ic_launcher);
return v;
}
}
执行看效果。之前。我须要贴出OnCreate方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); getNewsInfo(); ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new MyAdapter());
}
执行看效果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
执行效果为NULL指针异常,这是为什么呢?
既然NULL指针异常。代码是哪行有问题? 细致一看是
lv.setAdapter(new MyAdapter());
这是由于,我们的获取server的数据是在一个子线程中执行的,而我们setAdapter的任务是在主线程中获取的。这时候当我们的server数据还没获取完成,我们就设置数据了。就会导致异常发生。所以我们要当server的数据获取完后,才去设置adapter
改动代码:添加消息机制
//当数据接受完毕后,发生消息
handler.sendEmptyMessage(1); //打印
for (News n : newList) {
System.out.println(n.toString());
}
//在消息中设置数据
Handler handler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new MyAdapter());
};
};
这种话就出现了刚開始的截图。可是我们还须要优化listview
优化后的listview
public View getView(int position, View convertView, ViewGroup parent) { News news = newList.get(position);
ViewHolder mHolder;
View v = null;
//当缓冲为空的时候。创建view对象。并将组件封装到view的tag中
if(convertView == null)
{
v = View.inflate(MainActivity.this, R.layout.item_listview, null);
mHolder = new ViewHolder(); mHolder.tv_title = (TextView) v.findViewById(R.id.tv_title);
mHolder.tv_detail = (TextView) v.findViewById(R.id.tv_detail);
mHolder.tv_comment = (TextView) v.findViewById(R.id.tv_comment);
mHolder.siv = (ImageView)v.findViewById(R.id.iv);
v.setTag(mHolder);
}
else {//当缓冲不为空时。就将缓冲的数据取出来用,不用又一次创建,这样可节省系统资源
v = convertView;
mHolder =(ViewHolder) v.getTag();
}
//设置数据到组件
mHolder.tv_title.setText(news.getTitle());
mHolder.tv_detail.setText(news.getDetail());
mHolder.tv_comment.setText(news.getComment() + "条评论");
mHolder.siv.setImageResource(R.drawable.ic_launcher);
return v;
}
这样我们的从服务端的获取数据就算完毕了,可是我们还没获取server的图片资源,图片资源是通过一个地址封装到xml文件里的,我们须要再次拿到xml文件里的图片地址再次请求server获取图片资源,关于怎样获取server图片资源我上节都讲过了,这里就不做了。
Android 网络学习之获取server文本文件的更多相关文章
- Android网络编程要学的东西与Http协议学习
本节引言: 本节开始我们来学习Android网络编程相关的一些东西:Android端网络编程是要干嘛?http协议的学习,使用自带扣脚Json解析类解析Json,XML解析常用的几种方式,HttpUr ...
- Android开发学习之路--网络编程之xml、json
一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...
- Android网络(3):HttpClient作client,Tomcat Servlet作server的交互演示样例
前面相继介绍了Android网络编程里的Socket传输图片.HttpURLConnection,今天看HttpClient. 第一部分:JavaEE版的Eclipse配置Tomcat [备注:开发后 ...
- android菜鸟学习笔记31----Android使用百度地图API(二)获取地理位置及地图控制器的简单使用
1.获取当前地理位置: Android中提供了一个LocationManager的类,用于管理地理位置.不能通过构造函数获取该类的实例,而是通过Context的getSystemService(): ...
- Android网络框架Volley
Volley是Google I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...
- ym—— Android网络框架Volley(终极篇)
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103).谢谢支持! 没看使用过Volley的同学能够,先看看Android网络框架Volley(体验篇)和 ...
- 6、android 网络编程
1.基于socket的用法 服务器端: 先启动一个服务器端的socket ServerSocket svr = new ServerSocket(8989); 开始侦听请求 Socket s ...
- ios网络学习------4 UIWebView的加载本地数据的三种方式
ios网络学习------4 UIWebView的加载本地数据的三种方式 分类: IOS2014-06-27 12:56 959人阅读 评论(0) 收藏 举报 UIWebView是IOS内置的浏览器, ...
- Android网络编程只局域网传输文件
Android网络编程之局域网传输文件: 首先创建一个socket管理类,该类是传输文件的核心类,主要用来发送文件和接收文件 具体代码如下: package com.jiao.filesend; im ...
随机推荐
- PowerDesigner连接MySQL数据库
详细步骤请点击下面的链接查看! 我在网上找了很多篇教程, 其中这一篇是最好的. 可以成功的帮助我们把PowerDesigner和MySQL数据库相连. PowerDesigner真的非常强大! 设计数 ...
- jstl笔记
EL函数库 <%@page import="java.util.ArrayList"%> <%@ page language="java" c ...
- SDOI2015约数个数和
题目描述 题解: 有一个式子: 证明先不说了. 然后倒一波反演: 然后整除分块就好了. 代码: #include<cstdio> #include<cstring> #incl ...
- thinkphp 5.0整合阿里大于验证码短信发送接口,含完整模型验证实例DEMO
为大家分享一个阿里大于短信发送接口: 首先创建一个发送模型(Send.php): <?php namespace app\index\model; use think\Validate; cla ...
- JavaScript:获取上传图片的base64
文章来源:http://www.cnblogs.com/hello-tl/p/7661535.html 1.HTML代码 <!DOCTYPE html> <html lang=&qu ...
- rbac组件之数据库设计(一)
rbac是基于角色的权限设计,一共包含六张表,具体的表设计如下: from django.db import models class Menu(models.Model): "" ...
- 88-On Balance Volume 能量潮指标.(2015.7.4)
On Balance Volume 能量潮指标 ~计算方法: 如果当天的收盘价高于昨天的话,那么:OBV(i) = OBV(i-1)+VOLUME(i) 如果当天的收盘价低于昨天的话,那么:OBV(i ...
- 杭电1722 Cake (分蛋糕)
#include<cstdio> int f(int m,int n) { ) return n; else return f(n,m%n); } int main() { int m,n ...
- 集训第六周 数学概念与方法 计数 排列 L题
Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理一样. 话 ...
- hadoop_exporter+prometheus
1.准备工作 安装go.glibe(需要连google服务器,咋连的,我就不写了,因为尝试了各种办法,都失败了,很伤心) 2.下载hadoop_exporter cd /usr/local/prom/ ...