• 分分钟教你做出自己的新闻阅读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/

      <。)#)))≦

    评论
  • 相关阅读:
    Python Day23
    Python Day22
    Python Day21
    Python Day20
    Python Day19
    Python Day18
    Python Day17
    Python Day15
    Appium python unittest pageobject如何实现加载多个case
    Appium python Uiautomator2 多进程问题
  • 原文地址:https://www.cnblogs.com/voidy/p/4067777.html
Copyright © 2020-2023  润新知