分享一個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。共勉之。。。

 


免責聲明!

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



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