Android也架構之四:門面模式解析獲取的html代碼

你們好,一個星期沒有寫博客了,最近在找工做,面試中啊。。。。

上一篇文章《Android也架構之三:簡單工廠模式優化網絡請求》中,咱們知道了如何經過簡單工廠模式去獲取網絡的內容,又知道了如何把這些內容顯示在咱們的界面上,可是咱們拿到的都是html文本內容。這篇文章中,咱們將講到了如何去解析這些html,得到咱們想要的內容。php

經過這篇文章的學習,你將學會一下幾個知識點:html

1,門面模式在android中的應用java

2,學會使用jsoup框架解析html。node


廢話少說,咱們首先來看下什麼是門面模式:android

門面模式要求一個子系統的外部與其內部的通訊必須經過一個統一的門面(Facade)對象進行。門面模式提供一個高層次的接口,使得子系統更易於使用。    面試

門面(Facade)角色:客戶端能夠調用這個角色的方法。此角色知曉相關的(一個或者多個)子系統的功能和責任。在正常狀況下,本角色會將全部從客戶端發來的請求委派到相應的子系統去。編程

子系統(subsystem)角色:能夠同時有一個或者多個子系統。每個子系統都不是一個單獨的類,而是一個類的集合。每個子系統均可以被客戶端直接調用,或者被門面角色調用。子系統並不知道門面的存在,對於子系統而言,門面僅僅是另一個客戶端而已。json

在咱們一下的例子中,門面是facade.java,子系統有網絡系統(從網絡中獲取響應數據)和數據解析系統(解析html代碼)網絡


網絡系統的代碼能夠直接看上一篇文章《Android也架構之三:簡單工廠模式優化網絡請求》的代碼,這裏就不在貼出。架構

首先咱們來看一下html數據解析代碼:

[java]  view plain copy
  1. package com.devchina.analyze;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import org.jsoup.Jsoup;  
  7. import org.jsoup.nodes.Document;  
  8. import org.jsoup.nodes.Element;  
  9. import org.jsoup.select.Elements;  
  10. /** 
  11.  * @title HTML解析類 
  12.  * @description 描述 
  13.  * @company 探索者網絡工做室(www.tsz.net) 
  14.  * @author michael Young (www.YangFuhai.com) 
  15.  * @version 1.0 
  16.  * @created 2012-9-10 
  17.  */  
  18. public class HtmlAnalyze implements DataAnalyze {  
  19.   
  20.     @Override  
  21.     public List<String> getTitleList(String strData) {  
  22.         List<String> strList = new ArrayList<String>();  
  23.         Document doc = Jsoup.parse(strData,"utf-8");//得到document  
  24.         Element content = doc.body();//得到body  
  25.         Elements links = content.getElementsByTag("a");//得到全部的超級連接  
  26.           
  27.         for (Element link : links) { //遍歷全部的超級連接  
  28.           String linkHref = link.attr("href");  
  29.           String linkText = link.text();  
  30.             
  31.           System.out.println("---------linkHref:"+linkHref);  
  32.           System.out.println("---------linkText:"+linkText);  
  33.             
  34.           if(linkHref.startsWith("forum.php?mod=viewthread")) //若是是文章的超級連接的話,添加到list 返回  
  35.               strList.add(linkText);  
  36.             
  37.         }  
  38.           
  39.         return strList;  
  40.     }  
  41.   
  42. }  

數據解析接口和數據解析工廠類(爲何用工廠,能夠查看上一篇文章)

DataAnalyze.java

[java]  view plain copy
  1. package com.devchina.analyze;  
  2.   
  3. import java.util.List;  
  4. /** 
  5.  * @title 數據解析接口 
  6.  * @description 解析數據 
  7.  * @company 探索者網絡工做室(www.tsz.net) 
  8.  * @author michael Young (www.YangFuhai.com) 
  9.  * @version 1.0 
  10.  * @created 2012-9-10 
  11.  */  
  12. public interface DataAnalyze {  
  13.   
  14.     public List<String> getTitleList(String strData);  
  15. }  

DataAnalyzeFactory.java

[java]  view plain copy
  1. package com.devchina.analyze;  
  2.   
  3. /** 
  4.  * @title 數據解析工廠類 
  5.  * @description 描述 
  6.  * @company 探索者網絡工做室(www.tsz.net) 
  7.  * @author michael Young (www.YangFuhai.com) 
  8.  * @version 1.0 
  9.  * @created 2012-9-10 
  10.  */  
  11. public class DataAnalyzeFactory {  
  12.       
  13.     public static DataAnalyze getAnalyze(){  
  14.         //這裏很簡單,直接放回了html解析類,之後能夠經過擴展實現xml解析,json解析等功能  
  15.         return new HtmlAnalyze();  
  16.     }  
  17.   
  18. }  


接下來咱們來看下門面模式的核心類facade.java

[java]  view plain copy
  1. package com.devchina.facade;  
  2.   
  3. import java.util.List;  
  4.   
  5. import com.devchina.analyze.DataAnalyzeFactory;  
  6. import com.devchina.http.HttpFactory;  
  7.   
  8. /** 
  9.  * @title 獲取devchina.com的文章列表門面 
  10.  * @description 描述 
  11.  * @company 探索者網絡工做室(www.tsz.net) 
  12.  * @author michael Young (www.YangFuhai.com) 
  13.  * @version 1.0 
  14.  * @created 2012-9-10 
  15.  */  
  16. public class Facade {  
  17.   
  18.     //門面中獲取devchina.com的文章列表的方法  
  19.     public static List<String>  getTitleListFromDevChina(){  
  20.         //首選是經過網絡模塊去獲取www.devchina.com的html內容  
  21.         String strHtml = HttpFactory.getHttp().getUrlContext("http://www.devchina.com/forum.php?mod=forumdisplay&fid=63");  
  22.         //經過解析模塊獲取去解析得到到的內容(解析工廠中目前只有html解析,之後根據項目擴展能夠添加xml解析,json解析等)  
  23.         return strHtml != null ? DataAnalyzeFactory.getAnalyze().getTitleList(strHtml) : null;  
  24.     }  
  25. }  
這裏我多嘮叨幾句, 門面模式要求一個子系統(這裏的就是網絡子系統,數據解析子系統)的外部與其內部的通訊必須經過一個統一的門面(Facade)對象進行。門面模式提供一個高層次的接口,使得子系統更易於使用。

在這裏,咱們明顯的能感受到,當客戶端FacadeActivity要去實現某項功能的時候,無需與各個子系統去打交道,直接去門面獲取就好了,這樣就下降了耦合度,當未來因爲某些緣由,子系統改變了,咱們的客戶端的代碼也無需改變,同時子系統又採用了工廠模式,基於接口編程原則(可插拔),又給系統下降了一層的耦合。

FacadeActivity.java 這個是android用來顯示數據的activity組件

[java]  view plain copy
  1. package com.devchina.ui;  
  2.   
  3. import java.util.List;  
  4.   
  5. import com.devchina.facade.Facade;  
  6. import com.devchina.facade.R;  
  7. import com.devchina.facade.R.id;  
  8. import com.devchina.facade.R.layout;  
  9. import com.devchina.http.HttpFactory;  
  10. import com.devchina.http.HttpUtils;  
  11.   
  12. import android.app.Activity;  
  13. import android.graphics.Bitmap;  
  14. import android.graphics.BitmapFactory;  
  15. import android.graphics.drawable.BitmapDrawable;  
  16. import android.graphics.drawable.Drawable;  
  17. import android.os.Bundle;  
  18. import android.view.View;  
  19. import android.view.View.OnClickListener;  
  20. import android.widget.Button;  
  21. import android.widget.EditText;  
  22. import android.widget.TextView;  
  23.   
  24. /** 
  25.  * @title 客戶端的acitivity  
  26.  * @description (門面模式) 
  27.  * @company 探索者網絡工做室(www.tsz.net) 
  28.  * @author michael Young (www.YangFuhai.com) 
  29.  * @version 1.0 
  30.  * @created 2012-8-19 
  31.  */  
  32. public class FacadeActivity extends Activity {  
  33.   
  34.     TextView mTv;  
  35.   
  36.     @Override  
  37.     public void onCreate(Bundle savedInstanceState) {  
  38.         super.onCreate(savedInstanceState);  
  39.         setContentView(R.layout.main);  
  40.         mTv = (TextView) findViewById(R.id.textView);  
  41.   
  42.         mTv.setText("正在加載www.devchina.com數據。。。");  
  43.         new Thread(new Runnable() {  
  44.   
  45.             @Override  
  46.             public void run() {  
  47.                   
  48.                 //經過門面 直接去獲取www.devchina.com的文章列表,不用去和網絡模塊,解析模塊等模塊打交道,只管去門面獲取就好了  
  49.                 //就像咱們去買東西的時候,超市(facade)裏面已經有了不少東西了,咱們無需去和各個廠家打交道,咱們直接去超市獲取,無需知道超市是怎麼去和廠家溝通交流的  
  50.                 List<String> strList = Facade.getTitleListFromDevChina();  
  51.                   
  52.                 if(strList!=null && strList.size() >0){  
  53.                       
  54.                     String strContext = "";  
  55.                     for(String str : strList)  
  56.                         strContext += str;  
  57.                       
  58.                     final String showText = strContext;  
  59.                     System.out.println("-------strContext:" + strContext);  
  60.                     runOnUiThread(new Runnable() {  
  61.                         public void run() {  
  62.                             if (showText != null)  
  63.                                 mTv.setText(showText);  
  64.                             else  
  65.                                 mTv.setText("加載失敗。。。");  
  66.                         }  
  67.                     });  
  68.                 }  
  69.             }  
  70.         }).start();  
  71.   
  72.     }  
  73.   
  74. }  


如今代碼已經完畢。無圖無真相,上圖。

代碼下載地址:

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上》敬請關注。

相關文章
相關標籤/搜索