從零開始Gank客戶端開發(fā)之一

一直以來都感覺自己只會(huì)看代碼,解決bug,總是覺得自己能力有限,想做一些程序性的開發(fā),但總是做到一半就戛然而止。這次終于鼓起勇氣來從零開始做一款客戶端程序,一切從零開始。

由于從來沒有做過相應(yīng)的開發(fā),不敢說自己怎么組織架構(gòu),怎么設(shè)計(jì)項(xiàng)目等,都是隨著項(xiàng)目慢慢的深入,一步步發(fā)掘項(xiàng)目功能,然后不斷改進(jìn)的結(jié)果。這個(gè)系列的文章,權(quán)當(dāng)是某人的思路。

數(shù)據(jù)

首先我先想到的不是界面,而是數(shù)據(jù),數(shù)據(jù)從什么地方來,應(yīng)該怎么使用?很顯然我們這個(gè)項(xiàng)目使用的是干活集中營(yíng)的API,具體可以看http://gank.io/api

由于是網(wǎng)絡(luò)數(shù)據(jù),很自然就想到了okHttp了,當(dāng)然你可能想到了RxJava+Retrofit,可是為了從基本入手,我就選擇了okHttp了。

先簡(jiǎn)單裝一下okHttp
  1. 導(dǎo)入okHttp包
    只需在Gradle下添加如下依賴即可:
compile 'com.squareup.okhttp3:okhttp:3.6.0'
  1. 創(chuàng)建Manager類
    我這里創(chuàng)建的是GankHttpManager.java,這里我將其改為單例類型。
private static GankHttpManager mInstance;
private GankHttpManager() {
 }
public static GankHttpManager getInstance() {
        if(mInstance == null) {
            synchronized (GankHttpManager.class) {
                if(mInstance == null) {
                    mInstance = new GankHttpManager();
                }
            }
        }
        return mInstance;
    }

當(dāng)然GankHttpManage不可能這么簡(jiǎn)單,既然是封裝okHttp,當(dāng)然得需要OkHttpClient,解析數(shù)據(jù)也需要Gson,這些一并在構(gòu)造方法中初始化即可:

private OkHttpClient mHttpClient;
private Handler mHandler;
private Gson mGson;
private GankHttpManager() {
        mHttpClient = new OkHttpClient();
        mHandler = new Handler(Looper.getMainLooper());
        mGson = new Gson();
 }

這樣我們的GankHttpManager就封裝好了。現(xiàn)在我們要做的事情就是通過Gson來解析數(shù)據(jù)了。
通過查看干活集中營(yíng)的Api,可以發(fā)現(xiàn)暫時(shí)我們需要的Api有兩種類型,1. 每日數(shù)據(jù);2.分類數(shù)據(jù)。通過查看json數(shù)據(jù)可以發(fā)現(xiàn)這兩種Api的數(shù)據(jù)有些不一樣。

每日數(shù)據(jù)(http://gank.io/api/day/年/月/日)

我們先來看一下json數(shù)據(jù)

//省略號(hào)代表后面的重復(fù)性內(nèi)容省略
{
  "category": [
    "Android", ...
  ], 
  "error": false, 
  "results": {
    "Android": [
      {
        "_id": "590af3b3421aa90c7fefdd3c", ...
      }, ...
     ],...
   }
}

如果用Gson進(jìn)行解析那么我們應(yīng)該怎樣去構(gòu)建對(duì)象呢?
可以看到整個(gè)json包含三個(gè)大括號(hào),如果我們把大括號(hào)代表一個(gè)層級(jí)的話,那么就比較好分析了,
1.首先構(gòu)建一個(gè)對(duì)象包含三個(gè)參數(shù),category,error,results。那么最外層也就分析完了,
2.其次再看category,該對(duì)象中又包含中括號(hào),那么我們可以將之看作為一個(gè)List。再看results,你會(huì)發(fā)現(xiàn)其和包含的內(nèi)容和外層類似,可以把整個(gè)的result看做一個(gè)對(duì)象。這時(shí)你可能又郁悶了,如果把里面的每一個(gè)看做一個(gè)對(duì)象,但是對(duì)象里的內(nèi)容又是重復(fù)的,這怎么解決呢?其實(shí)可以把result看做是幾個(gè)不同的List就可以了。
經(jīng)過簡(jiǎn)單的分析那么我開始構(gòu)建我們的數(shù)據(jù)吧。首先構(gòu)建的是最里層相似的內(nèi)容。我將之封裝為Gank對(duì)象。

public class Gank{
    public String _id;
    public Date createdAt;
    public String desc;
    public Date publishedAt;
    public String source;
    public String type;
    public String url;
    public boolean used;
    public String who;
}

也可以加上@SerializedName的注解,來標(biāo)明對(duì)應(yīng)json的數(shù)據(jù)。

做完上面的工作,我們就可以來封裝整個(gè)json了,我將之封裝為DailyGank對(duì)象

public class DailyGank {
    @SerializedName("category") public List<String> category;
    @SerializedName("error") public boolean error;
    @SerializedName("results") public Result result;

    public class Result {
        @SerializedName("福利") public List<Gank> welfareList;
        @SerializedName("Android") public List<Gank> androidList;
        @SerializedName("iOS") public List<Gank> iosList;
        @SerializedName("拓展資源") public List<Gank> extraList;
        @SerializedName("前端") public List<Gank> frontList;
        @SerializedName("瞎推薦") public List<Gank> casualList;
        @SerializedName("App") public List<Gank> appList;
        @SerializedName("休息視頻") public List<Gank> videoList;
    }
}

這樣我們就封裝了每日數(shù)據(jù)的json對(duì)象,那么下面我們來封裝分類對(duì)象

分類對(duì)象(http://gank.io/api/data/數(shù)據(jù)類型/請(qǐng)求個(gè)數(shù)/第幾頁(yè))

同樣,我們可以看一下json數(shù)據(jù)

{
  "error": false, 
  "results": [
    {
      "_id": "590af3b3421aa90c7fefdd3c",...
    }, ...
   ]
}

可以看到和上面的數(shù)據(jù)有一點(diǎn)出入,也有相似點(diǎn)。我就不介紹了。直接看封裝ClassifyGank

public class ClassifyGank {
    @SerializedName("error") public boolean error;
    @SerializedName("results") public List<Gank> classifyGank;
}

或者我們可以將DailyGank和ClassifyGank中共有的屬性error給封裝到BaseGank中,然后繼承。不這樣也沒有關(guān)系。

既然我們的json數(shù)據(jù)已經(jīng)分析清楚了,那么就可以在GankHttpManager中來獲取并解析數(shù)據(jù)了。主要寫兩個(gè)方法,分別獲取每日數(shù)據(jù)和分類數(shù)據(jù)

public void getClassifyGank(String url, final GankHttpListener listener) {
        Request request = new Request.Builder().url(url).build();
        mHttpClient.newCall(request)
                .enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {

                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        final String body = response.body().string();
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                ClassifyGank data = mGson.fromJson(body,ClassifyGank.class);
                                // TODO: 處理數(shù)據(jù) 
                            }
                        });
                    }
                });
    }
public void getDailyGank(String url, final GankHttpListener listener){
        Request request = new Request.Builder().url(url).build();
        mHttpClient.newCall(request)
                .enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {

                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        final String body = response.body().string();
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                DailyGank data = mGson.fromJson(body,DailyGank.class);
                                // TODO: 處理數(shù)據(jù)
                            }
                        });
                    }
                });
    }

代碼中有一段注釋是用來處理數(shù)據(jù)用的,看見了嗎?在我們傳入方法的地方都有一個(gè)listener,那個(gè)就是用來進(jìn)行回調(diào)的方法,以便我們得到數(shù)據(jù)后進(jìn)行處理。后面會(huì)介紹該listener怎么去定義。


這次就先講到這里,下面一節(jié)講解Gank客戶端的主界面。拜拜!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評(píng)論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,711評(píng)論 19 139
  • 參考Android網(wǎng)絡(luò)請(qǐng)求心路歷程Android Http接地氣網(wǎng)絡(luò)請(qǐng)求(HttpURLConnection) 一...
    合肥黑閱讀 21,736評(píng)論 7 63
  • 參考資源 官網(wǎng) 國(guó)內(nèi)博客 GitHub官網(wǎng) 鑒于一些關(guān)于OKHttp3源碼的解析文檔過于碎片化,本文系統(tǒng)的,由淺入...
    風(fēng)骨依存閱讀 12,722評(píng)論 11 82
  • 敦煌!我向往的地方!
    莫愁2016閱讀 245評(píng)論 0 0

友情鏈接更多精彩內(nèi)容