zoukankan      html  css  js  c++  java
  • 分享一个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。共勉之。。。

  • 相关阅读:
    Mybatis中javaType和jdbcType对应关系
    spy日志
    mybatis批量插入和更新
    js打印方案
    js弹窗,父子窗口调用
    extjs4.1
    oracle开启远程连接访问
    javaweb打印
    Leetcode 392.判断子序列
    Leetcode 391.完美矩形
  • 原文地址:https://www.cnblogs.com/rwxwsblog/p/4910805.html
Copyright © 2011-2022 走看看