Android也架构之四:门面模式解析获取的html代码
上一篇文章《Android也架构之三:简单工厂模式优化网络请求》中,我们知道了如何通过简单工厂模式去获取网络的内容,又知道了如何把这些内容显示在我们的界面上,但是我们拿到的都是html文本内容。这篇文章中,我们将讲到了如何去解析这些html,获得我们想要的内容。
通过这篇文章的学习,你将学会一下几个知识点:
1,门面模式在android中的应用
2,学会使用jsoup框架解析html。
废话少说,我们首先来看下什么是门面模式:
门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
门面(Facade)角色:客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
子系统(subsystem)角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
在我们一下的例子中,门面是facade.java,子系统有网络系统(从网络中获取响应数据)和数据解析系统(解析html代码)
网络系统的代码可以直接看上一篇文章《Android也架构之三:简单工厂模式优化网络请求》的代码,这里就不在贴出。
首先我们来看一下html数据解析代码:
[java] view plain copy- packagecom.devchina.analyze;
- importjava.util.ArrayList;
- importjava.util.List;
- importorg.jsoup.Jsoup;
- importorg.jsoup.nodes.Document;
- importorg.jsoup.nodes.Element;
- importorg.jsoup.select.Elements;
- /**
- *@titleHTML解析类
- *@description描述
- *@company探索者网络工作室(www.tsz.net)
- *@authormichaelYoung(www.YangFuhai.com)
- *@version1.0
- *@created2012-9-10
- */
- publicclassHtmlAnalyzeimplementsDataAnalyze{
- @Override
- publicList<String>getTitleList(StringstrData){
- List<String>strList=newArrayList<String>();
- Documentdoc=Jsoup.parse(strData,"utf-8");//获得document
- Elementcontent=doc.body();//获得body
- Elementslinks=content.getElementsByTag("a");//获得所有的超级链接
- for(Elementlink:links){//遍历所有的超级链接
- StringlinkHref=link.attr("href");
- StringlinkText=link.text();
- System.out.println("---------linkHref:"+linkHref);
- System.out.println("---------linkText:"+linkText);
- if(linkHref.startsWith("forum.php?mod=viewthread"))//如果是文章的超级链接的话,添加到list返回
- strList.add(linkText);
- }
- returnstrList;
- }
- }
数据解析接口和数据解析工厂类(为什么用工厂,可以查看上一篇文章)
DataAnalyze.java
[java] view plain copy- packagecom.devchina.analyze;
- importjava.util.List;
- /**
- *@title数据解析接口
- *@description解析数据
- *@company探索者网络工作室(www.tsz.net)
- *@authormichaelYoung(www.YangFuhai.com)
- *@version1.0
- *@created2012-9-10
- */
- publicinterfaceDataAnalyze{
- publicList<String>getTitleList(StringstrData);
- }
DataAnalyzeFactory.java
[java] view plain copy
- packagecom.devchina.analyze;
- /**
- *@title数据解析工厂类
- *@description描述
- *@company探索者网络工作室(www.tsz.net)
- *@authormichaelYoung(www.YangFuhai.com)
- *@version1.0
- *@created2012-9-10
- */
- publicclassDataAnalyzeFactory{
- publicstaticDataAnalyzegetAnalyze(){
- //这里很简单,直接放回了html解析类,以后可以通过扩展实现xml解析,json解析等功能
- returnnewHtmlAnalyze();
- }
- }
接下来我们来看下门面模式的核心类facade.java
[java] view plain copy- packagecom.devchina.facade;
- importjava.util.List;
- importcom.devchina.analyze.DataAnalyzeFactory;
- importcom.devchina.http.HttpFactory;
- /**
- *@title获取devchina.com的文章列表门面
- *@description描述
- *@company探索者网络工作室(www.tsz.net)
- *@authormichaelYoung(www.YangFuhai.com)
- *@version1.0
- *@created2012-9-10
- */
- publicclassFacade{
- //门面中获取devchina.com的文章列表的方法
- publicstaticList<String>getTitleListFromDevChina(){
- //首选是通过网络模块去获取www.devchina.com的html内容
- StringstrHtml=HttpFactory.getHttp().getUrlContext("http://www.devchina.com/forum.php?mod=forumdisplay&fid=63");
- //通过解析模块获取去解析获得到的内容(解析工厂中目前只有html解析,以后根据项目扩展可以添加xml解析,json解析等)
- returnstrHtml!=null?DataAnalyzeFactory.getAnalyze().getTitleList(strHtml):null;
- }
- }
在这里,我们明显的能感觉到,当客户端FacadeActivity要去实现某项功能的时候,无需与各个子系统去打交道,直接去门面获取就行了,这样就降低了耦合度,当将来由于某些原因,子系统改变了,我们的客户端的代码也无需改变,同时子系统又采用了工厂模式,基于接口编程原则(可插拔),又给系统降低了一层的耦合。
FacadeActivity.java 这个是android用来显示数据的activity组件
[java] view plain copy- packagecom.devchina.ui;
- importjava.util.List;
- importcom.devchina.facade.Facade;
- importcom.devchina.facade.R;
- importcom.devchina.facade.R.id;
- importcom.devchina.facade.R.layout;
- importcom.devchina.http.HttpFactory;
- importcom.devchina.http.HttpUtils;
- importandroid.app.Activity;
- importandroid.graphics.Bitmap;
- importandroid.graphics.BitmapFactory;
- importandroid.graphics.drawable.BitmapDrawable;
- importandroid.graphics.drawable.Drawable;
- importandroid.os.Bundle;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- importandroid.widget.EditText;
- importandroid.widget.TextView;
- /**
- *@title客户端的acitivity
- *@description(门面模式)
- *@company探索者网络工作室(www.tsz.net)
- *@authormichaelYoung(www.YangFuhai.com)
- *@version1.0
- *@created2012-8-19
- */
- publicclassFacadeActivityextendsActivity{
- TextViewmTv;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- mTv=(TextView)findViewById(R.id.textView);
- mTv.setText("正在加载www.devchina.com数据。。。");
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- //通过门面直接去获取www.devchina.com的文章列表,不用去和网络模块,解析模块等模块打交道,只管去门面获取就行了
- //就像我们去买东西的时候,超市(facade)里面已经有了很多东西了,我们无需去和各个厂家打交道,我们直接去超市获取,无需知道超市是怎么去和厂家沟通交流的
- List<String>strList=Facade.getTitleListFromDevChina();
- if(strList!=null&&strList.size()>0){
- StringstrContext="";
- for(Stringstr:strList)
- strContext+=str;
- finalStringshowText=strContext;
- System.out.println("-------strContext:"+strContext);
- runOnUiThread(newRunnable(){
- publicvoidrun(){
- if(showText!=null)
- mTv.setText(showText);
- else
- mTv.setText("加载失败。。。");
- }
- });
- }
- }
- }).start();
- }
- }
现在代码已经完毕。无图无真相,上图。
代码下载地址:
http://download.csdn.net/detail/michael_yy/4561839
文章出处说明来之CSDN:http://blog.csdn.net/michael_yy/article/details/7965168
大家多多指教,转载请注明来之http://www.devchina.com/或者http://blog.csdn.net/michael_yy, 谢谢。
谢谢大家关注,我继续在博客中讲解了经典的23中模式中在android实际项目中灵活运用,下一篇 《Android也架构之五:适配器模式把html文章列表显示在android的listview上》敬请关注。
更多相关文章
- Android task和back stack详解四:intent中定义启动模式
- google 分屏 横屏模式 按home键界面错乱故障分析(二) 分屏的启动过
- [android盈利模式探索]我也分享一下我Android的收入数据
- Android View 高级框架二 Builder模式打造通用对话框