分分鍾教你做出自己的新聞閱讀APP


分分鍾教你做出自己的新聞閱讀APP

引子

  曾經不小心發現了一些好的看新聞的網站,但是電腦又不是隨身攜帶,因此想要下載一個這個網站的手機APP來看新聞,但是問題來了,這個網站根本沒有做Android端!你說用手機瀏覽器來看?天,有些網站用手機瀏覽器來看又會出現好些個問題,比如說:廣告太多,還有那令人厭惡的彈窗,更有些排版簡直讓人不忍直視有木有。因此,我萌生出一個自己打造一個新聞閱讀器的APP的想法,畢竟以前也玩過Android的開發,雖然是菜鳥級別的,但是做出一個手機新聞閱讀APP還是難不倒我的~

  工欲善其事,必先利其器

  開發工具:安裝過Android插件的Eclipse。

  必備jar包:jsoup-1.7.2.jar,(當然,其它版本也可以)

  必備知識:一點Android知識,一點HTML知識

技術原理

  技術上來講毫無難點。具體實現步驟如下:

  • 連接新聞網站的首頁
  • 抓取HTML的內容
  • 解析抓取的HTML網頁中的標題以及文章鏈接
  • 將所有標題顯示在當前頁,並將標題以及文章鏈接傳到下一個頁面
  • 抓取文章鏈接內容,和上頁傳來的標題一起顯示在當前頁

 看的再多不如動手一試 

  由於快點看出效果,所以一切就從簡了。直接建立Android項目,建立空的Activity。然后在你的layout的 這個文件中加入一個按鈕。比如像這樣:

<Button
        android:id="@+id/button1"
        android:layout_width="150dip"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/textView1"
        android:layout_alignBottom="@+id/textView1"
        android:layout_alignLeft="@+id/button2"
        android:background="@drawable/button"
        android:text="Business Insider" />

   然后在MainActivity里的onCreateView函數里加入一個方法,讓它能點擊你剛剛添加的按鈕進入到下一個界面: 

1 rootView.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
2                 
3                 @Override
4                 public void onClick(View v) {
5                     // TODO Auto-generated method stub
6                     StartGeek();
7                 }
8 
9             });

   點擊按鈕會觸發事件,執行StartGeek的方法,而StartGeek的方法則是跳到下一個Activity,  

1 private void StartGeek() {
2             // TODO Auto-generated method stub
3             Intent intent = new Intent();
4             intent.setClass(this.getActivity(), GeekActivity.class);
5             startActivity(intent);
6             
7         }    
StartGeek

   在這個Activity中,我們將訪問網頁,並從中獲取HTML網頁的內容,然后進行解析,獲取新聞的標題以及鏈接,然后將新聞的標題顯示在手機屏幕上,代碼具體實現如下:

1     ListView listview;
2     Handler handler;
3     List<Map<String, Object>> data;
4     
5     final String CSDNURL = "http://tech.qq.com/bi.htm";     

   首先是變量的聲明,至於變量名的問題請隨意吐槽,因為一直在嘗試拿各種網站的新聞內容,所以變量名是最初的,由於懶就一直沒換-。 -,由於新聞網站的內容較多,所以用ListView比較合適,這樣不會出現顯示不全的情況。

1 @Override
2     protected void onCreate(Bundle savedInstanceState) {
3         super.onCreate(savedInstanceState);
4         setContentView(R.layout.activity_geek);
5         handler = getHandler();
6         ThreadStart();
7     } 
 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     tools:context="${packageName}.${activityClass}" >
 6 
 7     <ListView      
 8         android:id="@+id/listView"
 9         android:layout_width="wrap_content"
10         android:layout_height="fill_parent"
11         ></ListView>
12 
13 </RelativeLayout>
activity_geek.xml

  接下來是onCreate方法,這里界面是activity_geek,然后調用兩個方法,由於獲取數據費時,所以又起了一個線程,當然比較好的方法是用異步線程來做,那樣的話不僅可以不占用主線程,而且還可以很方便的加進度條什么的,相當好用,至於我為什么不用,當然是不會用了撒~ 

 1 private void ThreadStart() {
 2         new Thread() {
 3             public void run() {
 4                 Message msg = new Message();
 5                 try {
 6                     data = getCsdnNetDate();
 7                     msg.what = data.size();
 8                 } catch (Exception e) {
 9                     e.printStackTrace();
10                     msg.what = -1;
11                 }
12                 handler.sendMessage(msg);
13             }
14         }.start();    
15     }
ThreadStart

  這是新的線程,用於從網址獲取我們想要的HTML文件,並將其傳給handler處理。獲取的函數方法是:

1 data = getCsdnNetDate();
 1 private List<Map<String, Object>> getCsdnNetDate() {
 2         List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
 3         Document doc = http_get(CSDNURL);
 4         Elements links = doc.select("h3>a");
 5         for(Element link: links)
 6             {
 7                 Map<String, Object> map = new HashMap<String, Object>();
 8                 map.put("title", link.attr("title"));
 9                 map.put("url", link.attr("abs:href"));
10                 result.add(map);
11             }
12 
13         
14         return result;
15     }
getCsdnNetDate 
1 Document doc = http_get(CSDNURL);
 1 private Document http_get(String url) {
 2         Document doc=null;
 3         try {
 4             doc = Jsoup.connect(url)
 5                     .timeout(50000)
 6                     .get();
 7         } catch (IOException e) {
 8             // TODO Auto-generated catch block
 9             e.printStackTrace();
10         }
11 
12         return doc;
13     }
http_get

  通過http_get方法中的Jsoup.connect來連接到網址,然后通過.get方法來獲得HTML的文本信息,設定的連接時間是5S,獲取到這個文本信息之后Jsoup還帶有解析方法,通過link.attr("title")來獲取HTML中的<title>標簽中的標題,然后再通過link.attr("abs:href")來獲取新聞中的鏈

接,由此,我們就獲得了HTML中最為重要的兩部分,也就是標題以及鏈接,事情到這里已經完成大半了,接下來就是將標題顯示在當前頁面,然后點擊標題后,能將標題以及文中內容顯示在下個頁面,處理的方法如下:

 1 private Handler getHandler() {
 2         return new Handler(){
 3             public void handleMessage(Message msg) {
 4                 if (msg.what < 0) {
 5                     Toast.makeText(GeekActivity.this, "數據獲取失敗", Toast.LENGTH_SHORT).show();
 6                 }else {
 7                     initListview();
 8                 }
 9             }
10         };
11     }
getHandler

  此方法會判斷數據是否為空,若為空則在手機屏幕跳出:數據獲取失敗的字樣,當然了,喜歡什么就改成什么,隨你所想~然后成功獲取數據則會進入到initListview方法:  

 1 private void initListview() {
 2         listview = (ListView)findViewById(R.id.listView);
 3         SimpleAdapter adapter = new SimpleAdapter(this, data,
 4                 android.R.layout.simple_list_item_1, new String[] { "title"},
 5                 new int[] { android.R.id.text1 });
 6         listview.setAdapter(adapter);
 7         
 8     
 9         listview.setOnItemClickListener(new OnItemClickListener() {
10             @Override
11             public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
12                     long arg3) {
13                 Map<String, Object> map = data.get(arg2);
14                 String url = (String)(map.get("url"));
15                 String title = (String)(map.get("title"));
16                 Intent intent = new Intent();
17                 intent.putExtra("url", url);
18                 intent.putExtra("title", title);
19                 intent.setClass(GeekActivity.this, ContentActivity.class);
20                 startActivity(intent);
21             }
22         });
23     }
initListview

  這個方法會將獲取的新聞標題顯示在當前頁面上,然后將新聞的標題以及鏈接保存下來,通過intent傳到下一個Activity,也就是ContentActivity進行處理,並將標題以及內容顯示在下一個頁面中。代碼的分下如下:

 1 @Override
 2     protected void onCreate(Bundle savedInstanceState) {
 3         super.onCreate(savedInstanceState);
 4         setContentView(R.layout.activity_content);
 5         
 6         url = getIntent().getStringExtra("url");
 7         String title = getIntent().getStringExtra("title");
 8         TextView tv = (TextView)findViewById(R.id.title_content);
 9         tv.setText(title);
10         handler = getHandler();
11         ThreadStart();
12     }
onCreate

  onCreate方法中獲取上個Activity中傳過來的url以及title,然后直接將新聞標題顯示在當前頁,然后剩余部分和上個方法差不太多,連接到網上,獲取HTML內容,這次在方法中僅僅是解析的方法不同,畢竟這次解析是要獲取內容嘛~代碼如下:

 1 private List<Map<String, Object>> getCsdnNetDate() {
 2         List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
 3         Document doc = http_get(url);
 4         Elements links = doc.select("div#Cnt-Main-Article-QQ>p");
 5         for(Element link: links)
 6             {
 7                 Map<String, Object> map = new HashMap<String, Object>();
 8                 map.put("title", link.text());
 9                 result.add(map);
10             }
11 
12         
13         return result;
14     }

  標紅部分為與上次不同的部分,這個解析都是用的Jsoup自帶的,當然正則表達式也是可以做到的哦,咳咳,我承認我很懶的啊,有好用的工具就直接用了,省時省力的事干嘛不用呢,就像寫網站有框架了自然就用了,不喜歡用的我也木有辦法,你可以使用正則表達式來做,話說以前用

Python做爬蟲的時候就是正則表達式做的。

  至此一個小的新聞的閱讀APP就出世了,哦,對了,不要忘了在你的配置文件加入Activity以及上網許可,不然的話是會閃退的哦。當然這個APP很是粗糙,有時間的人可以將圖片也加上進行一下頁面的設計,做一下美工什么的。

 

  PS:本博客歡迎轉發,但請注明博客地址及作者~

  博客地址:http://www.cnblogs.com/voidy/

  <。)#)))≦

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM