网页新闻抓取(new.xml通过HttpClient抓取网页新闻的demolist3. )

优采云 发布时间: 2021-10-21 15:12

  网页新闻抓取(new.xml通过HttpClient抓取网页新闻的demolist3.

)

  一、概览

  这是一个通过HttpClient抓取网页新闻的demo。涉及知识点:通过HttpClient从网上获取新闻(整理成XML格式),拉取解析XML,Android下ListView的使用和优化,将XML资源文件转换为视图视图,Android下的简单布局,Android消息处理机制。这里使用的网页消息是在tomcat下的一个WEB应用程序中用new.xml模拟的。虚拟机可以通过以下链接访问本机:8080/应用程序名称/new.xml。

  二、步骤

  说说思路:将新闻内容封装在JavaBean中(新闻内容包括图片、标题、详细信息、发帖数)。创建Activity时,启动子线程访问网络资源(因为Android4.0之后不支持主线程访问网络资源,会抛出异常:

  

  )。解析得到的XML文件,遍历节点获取新闻信息并封装成bean加入集合中,将该集合通过Message发送给主线程的Handler对象进行处理(只有主线程可以修改用户interface),然后自定义一个适配器,将新闻bean的内容添加到指定控件中,并为ListView指定当前的适配器来显示新闻。

  主要代码分为以下几部分:

  1.从网络获取XML文件的输入流

   /**

* 从网络上获取新闻输入流

* @return 新闻bean组成的list集合

*/

protected List getNewsFromIntenet() {

HttpClient client = null;

try {

// 定义一个客户端

client = new DefaultHttpClient();

HttpGet get = new HttpGet("http://10.0.2.2:8080/Example/new.xml");// 访问网络资源

HttpResponse response = client.execute(get);// 执行get请求得到响应

int code = response.getStatusLine().getStatusCode();// 获得状态码

if(code == 200){// 请求成功,得到数据并返回

InputStream in = response.getEntity().getContent();// 获得内容输入流

newsList = getNewsListFromInputStream(in);// 根据流解析指定XML

return newsList;// 返回新闻bean组成的list集合

}else{

// 请求失败,打印日志

Log.i(TAG, "请求失败,请检查代码" + code);

}

} catch (Exception e) {

e.printStackTrace();

}finally{

if(client != null){

client.getConnectionManager().shutdown();// 关闭客户端资源

}

}

return null;

}

  2.解析XML文件获取新闻bean列表

  /**

* 从XML中解析newsList

* @return News组成的集合

* @throws Exception

*/

private List getNewsListFromInputStream(InputStream in) throws Exception {

XmlPullParser parser = Xml.newPullParser();// 创建一个解析XML的pull解析器

parser.setInput(in, "utf-8");

int eventType = parser.getEventType();// 获取事件类型

List list = null;

NewsInfo newsInfo = null;

while(eventType != XmlPullParser.END_DOCUMENT){

String tagName = parser.getName();// 获取标签名

switch(eventType){

case XmlPullParser.START_TAG:// 设置指定的内容

if("news".equals(tagName)){

list = new ArrayList();

}else if("new".equals(tagName)){

newsInfo = new NewsInfo();

}else if("title".equals(tagName)){

newsInfo.setTitle(parser.nextText());

}else if("detail".equals(tagName)){

newsInfo.setDetail(parser.nextText());

}else if("comment".equals(tagName)){

newsInfo.setComment(Integer.valueOf(parser.nextText()));

}else if("image".equals(tagName)){

newsInfo.setImage(parser.nextText());

}

break;

case XmlPullParser.END_TAG:

if("new".equals(tagName)){// 一个new结束,将封装好的新闻bean添加到集合中

list.add(newsInfo);

}

break;

default:

break;

}

eventType = parser.next();// 取下一个事件类型

}

return list;

}

  3.将获取到的信息通过Message发送给Handler

   /**

* 初始化操作,开启新的线程去网络获取资源

*/

public void init() {

lvNews = (ListView) findViewById(R.id.lv_news);// 找到用来显示新闻的ListView

new Thread(new Runnable(){// 开启一个线程去访问网络资源

@Override

public void run() {

List newsList = getNewsFromIntenet();

Message msg = new Message();

if(newsList != null){

msg.what = SUCCESS;// 指定消息类型

msg.obj = newsList;

}else{

msg.what = FAILED;

}

handler.sendMessage(msg);// 发送消息

}

}).start();// 开启线程

}

  4.Handler根据Message类型进行相应处理:列表为空时提示错误,非空时通过adapter将信息显示在ListView上

  适配器核心代码:

  public View getView(int position, View convertView, ViewGroup parent) {

View view = null;

ViewHolder holder = null;

if(convertView == null){

holder = new ViewHolder();

view = View.inflate(MainActivity.this, R.layout.layout_news_list, null);

holder.sivIcon = (SmartImageView) view.findViewById(R.id.image);

holder.tv_title = (TextView) view.findViewById(R.id.tv_title);

holder.tv_comment = (TextView) view.findViewById(R.id.tv_comment);

holder.tv_detail = (TextView) view.findViewById(R.id.tv_detail);

holder.sivIcon.setImageUrl(newsList.get(position).getImage()); // 设置图片

holder.tv_title.setText(newsList.get(position).getTitle());

holder.tv_comment.setText(newsList.get(position).getComment() + "跟帖");

holder.tv_detail.setText(newsList.get(position).getDetail());

view.setTag(holder);// 将holder对象中的成员变量添加到view中

}else{

System.out.println("复用以前的view,位置:"+position);

view = convertView;

holder = (ViewHolder) view.getTag();

holder.sivIcon.setImageUrl(newsList.get(position).getImage()); // 设置图片

holder.tv_title.setText(newsList.get(position).getTitle());

holder.tv_comment.setText(newsList.get(position).getComment() + "跟帖");

holder.tv_detail.setText(newsList.get(position).getDetail());

}

return view;

}

  注意:

  XML资源文件转换为视图的三种方式,底层实现是一样的,这里是如下方式: view = View.inflate(MainActivity.this, R.layout.layout_news_list, null);

  在优化ListView时,可以通过重用convertView来减少视图的创建次数,此外还可以通过定义一个类来将视图中的控件声明为成员,例如上面的ViewHolder类。

  最后是最后的渲染:

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线