分享一个Cnblogs简易APP

  最近在学习Android app的开发,俗话说万事开头难,本人也不例外。计算机编程是属于一门要求动手能力和动脑能力都很强的学科,相信很多人都会有这样的经历,看得懂不去用,过不了几天也就忘记了。因而,在学习android开发的时候总想找个项目来实践实践。思来想去也没有找到什么好的点子,索性在此拿cnblogs来开刀。这是一个非常简单的应用,高手请自动飘过;初学者共勉之。

  此次的例子包含了客户端和服务器端,具体情况如下。

  一、开发环境:

  服务器端:采用PHP + Python的方式。

    数据来源:采用scrapy进行抓取的数据,见:http://www.cnblogs.com/rwxwsblog/tag/%E7%88%AC%E8%99%AB/

    Json数据:采用ThinkPhp写的简单页面

  测试环境:小米4

  开发工具:Android Studio、PhpStudy

  compileSdkVersion:23

  二、功能:

    1、最新消息

    2、图片轮播

    3、收藏

    4、查看原文

    5、分享

    目前只有这几个简单的功能,更多功能会在后续的开发中陆续引入。有什么好建议请给我留言吧。

  三、知识点:

    1、Navigation Drawer的用法
    2、SharedPreferences
    3、SQLite
    4、AsyncTask的运用
    5、主线程UI更新Handler
    6、PullToRefresh的运用
    7、Volley库的运用
    8、轮播图ViewPager等

  四、怎么可以少得了代码

    1、Handler更新UI主线程,见:Android app主线程UI更新间歇性崩溃的问题

    private Handler handlerListView = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle bundle = (Bundle) msg.obj;
            int refreshType = (int) bundle.get("refreshType");
            LinkedList<Article> list = (LinkedList<Article>) bundle.get("article");
            for (Article article : list){
                if (REFRESH_TYPE_UP == refreshType){
                    listData.add(article);
                }else if (REFRESH_TYPE_DOWN == refreshType){
                    listData.add(0, article);
                }
            }

            pullToRefreshView.onRefreshComplete();
            adapter.notifyDataSetChanged();
        }
    };

    2、PullToRefresh上拉和下拉刷新,更多内容见:Android PullToRefreshListView上拉刷新和下拉刷新

        pullToRefreshView = (PullToRefreshListView) rootView.findViewById(R.id.pull_to_refresh_listview);
        pullToRefreshView.setMode(PullToRefreshBase.Mode.BOTH);//两端刷新
//        pullToRefreshView.setMode(PullToRefreshBase.Mode.PULL_FROM_START);//上拉刷新
//        pullToRefreshView.setMode(PullToRefreshBase.Mode.PULL_FROM_END);//下拉刷新
        pullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {

            @Override
            public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
                refreshView.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.loading));
                refreshView.getLoadingLayoutProxy().setPullLabel(getString(R.string.downnloadmore));
                refreshView.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.startload));
//                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后加载时间:");
                if (1 == position) {
                    getArticleList(1, REFRESH_TYPE_DOWN);
                } else if (2 == position) {
                    new GetDataTask().execute(1, REFRESH_TYPE_DOWN);
                }
            }

            @Override
            public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
                refreshView.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.loading));
                refreshView.getLoadingLayoutProxy().setPullLabel(getString(R.string.uploadmore));
                refreshView.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.startload));
//                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后加载时间:");
                if (1 == position) {
                    int localPage = (int) (articleDao.getArticleCount(where, whereArgs) / ArticleDao.PAGE_ROW);
                    if (localPage > curPage) {
                        new GetDataTask().execute(curPage + 1, REFRESH_TYPE_UP);
                    } else {
                        getArticleList(curPage + 1, REFRESH_TYPE_UP);//如果本地没有则从服务器中获取
                    }
                } else if (2 == position) {
                    new GetDataTask().execute(curPage + 1, REFRESH_TYPE_UP);
                }
            }
        });

  3、Volley获取json格式数据,更多内容见:Android Volley获取json格式的数据

final LinkedList<Article> newsArticleList = new LinkedList<Article>();
        final RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
        String url = Article.ARTICLE_LIST_JSON_URL + "?p=" + page;
        final JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET,
                url, null, new Response.Listener<JSONArray>() {

            @Override
            public void onResponse(JSONArray response) {
                int length = response.length();
                try {
                    JSONObject jsonObject;
                    Article article;
                    for (int i = 0; i < length; i++) {
                        jsonObject = response.getJSONObject(i);
                        article = new Article();
                        article.setTitle(jsonObject.getString("title"));
                        article.setLink(jsonObject.getString("link"));
                        article.setLinkmd5id(jsonObject.getString("linkmd5id"));
                        article.setDesc(jsonObject.getString("desc"));
                        article.setView(jsonObject.getInt("view"));
                        article.setComment(jsonObject.getInt("comment"));
                        article.setDiggnum(jsonObject.getInt("diggnum"));
                        newsArticleList.add(article);
                    }

                    for (Article acl : newsArticleList) {
                        boolean flag = false;
                        for (Article articleLocal : listData) {
                            if (acl.getLinkmd5id().equals(articleLocal.getLinkmd5id())) {
                                flag = true;
                                break;
                            }
                        }
                        if (!flag) {
                            articleDao.addArticleToDb(acl);
                            if (REFRESH_TYPE_DOWN == refreshType) {
                                listData.add(0, acl);
                            } else if (REFRESH_TYPE_UP == refreshType) {
                                listData.add(acl);
                            }
                        }
                    }

                    pullToRefreshView.onRefreshComplete();
                    //刷新数据
                    adapter.notifyDataSetChanged();
                    curPage = page;
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        });
        requestQueue.add(jsonArrayRequest);

  就举这几个例子吧。

  五、代码看完了,说说几点经历吧:

  1、万事开头难。从开始到这个简易App的诞生,首先要面临的是数据如何提供的问题。当然可以用线程的通用系统如ecshop、wordpress等的现成程序,但由于懒得填充文章。采用的是scrapy直接抓取内容入库的方式。因而,首先搞定的事情是数据的获取。

  2、如何获取服务器数据。由于涉及到异步加载的问题,所以采用了google提供的volley;当然你也可以采用AsyncTask结合HttpClient进行获取。然而采用Volley的方式最为简易。  

  3、主UI的设计和刷新加载问题。主UI采用的是Android Studio提供的Navigation Drawer;然而上拉刷新和下拉刷新秉承着不重复造轮子的原则找来了PullToRefresh,然而PullToRefresh的整合(见Android Studio项目整合PullToRefresh的问题记录)由于对Gradle不熟悉,又大费周折。陆续地也就实现了上拉和下拉刷新的功能。

  4、由于涉及到数据存储和收藏的问题,因而采用的Sqlite进行数据的存储和收藏的标记。

  5、然而这只是粗略的一点记录。在开发中,随着功能的引入免不了代码的重构,因而很多代码看起来已经不是最初的样子了。当然,现在的代码仍然需要重构才能显得更为优雅。然而丑媳妇总要见公婆的嘛,后续加入功能再逐步加以优化吧。

  6、应用间歇性崩溃的问题。由于一开始没有采用Handler的方式进行主UI的更新,因而导致主UI间歇性地出现崩溃的现象。更多内容见:Android app主线程UI更新间歇性崩溃的问题

  好了,就先说这么多吧。大家有什么建议呢?请给我留言,谢谢!代码更新在这,https://github.com/jackgitgz/CnblogsApp。共勉之。。。

 

时间: 2024-10-02 07:03:50

分享一个Cnblogs简易APP的相关文章

分享一个PHP简易的图片相似度比较类

由于相似图片搜索的php实现的 API 不怎么符合我的用途,所以我重新定义 API 的架构,改写成比较简单的函数方式,虽然还是用对象的方式包装.  代码如下 复制代码 <?php    /**   * 图片相似度比较   *   * @version     $Id: ImageHash.php 4429 2012-04-17 13:20:31Z jax $   * @author      jax.hu   *   * <code>   *  //Sample_1   *  $aHas

android-使用 ACTION_SEND 打开 Share Dialog 来分享一个文件

问题描述 使用 ACTION_SEND 打开 Share Dialog 来分享一个文件 我知道使用 ACTION_SEND 能分享一个 text. Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "Download Link https://play.google.com/store/apps/details?id=

分享一个批量导出当前实例下的所有linkedserver脚本

原文:分享一个批量导出当前实例下的所有linkedserver脚本 分享一个批量导出当前实例下的所有linkedserver脚本 很多时候,我们都需要导出实例下面的登录用户,job,linkedserver等等 导出job比较复杂,下午写了一个脚本把所有的linkedserver导出来,但是密码不会显示出来 下面脚本在SQL2008 R2下面测试通过 -- ============================================= -- Author: <桦仔> -- Blog

让别人能够分享到我的app

问题描述 让别人能够分享到我的app 如题,要实现一个功能,就是用户在其他应用中选择分享时,能够出现我的app,并且能够分享到我的app的朋友圈动态中,应该怎样实现,就像微信的朋友圈 一样. 解决方案 这个要去申请的,微信和微博都有专门的接口,开发者得自己去申请 解决方案二: 到你希望接入的平台申请接口 解决方案三: 解决方案四: 这是系统的图库,点击分享能够分享到各种应用,自己的app怎样做才能让用户在这里选择自己的app

【有奖调查】作为一个偷懒的App开发者,你都用到哪些App开发工具或平台

问题描述 作为一个偷懒的App开发者,你都用到哪些App开发工具或平台,或是直接上手写原生代码? 我这里说的开发工具,是类似于appcan , apicloud, crossapp 这类的,可以帮助快速做app的. 一些通用的工具就不要说了哈,比如程序员鼓励师,UltraEdit,eclipse,键盘,鼠标啥的大家都知道的就不要说了哈:)  请说明:1.采用了什么样的开发工具或平台2.好用不, 都有啥功能?3.用这个解决了开发过程中的什么问题  都请大声的说出来吧,我们将根据回复抽出20个,送出

Vine很酷,任何人都能在6秒内分享一个短片

摘要: Vine很酷,任何人都能在6秒内分享一个短片,动画或者爆炸新闻.不过上面的内容千奇百怪,对孩子们的心智要求还是挺高的. 据Re/code消息,短视频领域的鼻祖Vine在周五推出了儿童版 Vine很酷,任何人都能在6秒内分享一个短片,动画或者爆炸新闻.不过上面的内容千奇百怪,对孩子们的"心智要求"还是挺高的. 据Re/code消息,短视频领域的鼻祖Vine在周五推出了儿童版的Vine Kids.Vine Kids更像是一个孩子们手机端的小玩具,省去了注册和关注环节,只需左右滑动,

Illustrator绘制一个有质感APP图标教程

给各位Illustrator软件的使用者们来详细的解析分享一下绘制一个有质感APP图标的教程. 教程分享: 在Ai软件中,新建一个800*800的文档,选择矩形工具,按住shift画一个正方形,并填充颜色,如图所示   然后选中正方形到效果-风格化-圆角,如图所示     接着选中圆角图形到对象-路径-偏移路径,并填充颜色,如图所示       接下来选择字体工具,写上文字,如图所示   最后选择椭圆工具,画一个椭圆图形,并添加渐变颜色,如图所示   效果如下图所示   好了,以上的信息就是小编

分享一个可以获取远程网站CSS配色的工具网站

分享一个通过读取远程网站的CSS文件,自动生成该网站配色方案的在线工具网站,推荐大家收藏... 在下面输入对方网站的网址后,轻松取得该网站CSS中应用到的配色色值. http://redalt.com/Tools/I+Like+Your+Colors 试一下吧!

V5Shop分享一个独立网店快速提升PR和销售额的方法

V5Shop分享一个独立网店快速提升PR和销售额的方法 很多独立网店的店主都在为宣传推广头疼.在现在这个产品丰富的市场经济环境下,各行各业的竞争都异常激烈,"酒香也怕巷子深"已经成为网商们的共识.作为独立网店,独立运营固然可以避免许多"拼低价"的竞争,客户对网店和品牌的忠诚度也有保证,但是在推广这个问题上,却难住了不少网商. 许多网商之所以过于依赖淘宝等大型平台,就是因为这些平台能够为其带来源源不断的客户,其不用为如何招揽客户,如何推广网店而劳心.有得必有失,这同样