Android學習筆記(九)--Retrofit初探索&Rxjava來摻和

爲了填補上篇博客立的flag,最近也是學習了一下Retrofit以及和Rxjava的聯合使用,下面就我遇到的一些困難來跟大家共同探討一下,同時自己也再梳理一遍。先來從Retrofit說起吧。
在我看來,Retrofit就是將網頁上的api接口轉化爲能在java中調用的接口,所以呢與一般的庫的使用也不太一樣,需要註冊對應的interface,將java和web聯繫起來,然後藉助Rxjava來處理web返回的消息。接下來就來看一下它簡單的使用。

compile 'com.squareup.retrofit2:retrofit:2.1.0'

首先要添加依賴,版本號可以去github看看使用最新的版本。下面就來看一下具體的使用吧,爲了避免混淆,先講不使用Rxjava的。

一、創建實例

Retrofit weatherTry=new Retrofit
.Builder()                                      .baseUrl("http://apis.baidu.com/heweather/weather/free/")
.client(new OkHttpClient())
.build();

這裏就是在百度api上隨便找的一個http://apistore.baidu.com/apiworks/servicedetail/478.html 可以點進去看一下具體的要求。Retrofit2 的baseUlr 必須以 /(斜線) 結束,不然會拋出一個IllegalArgumentException,所以如果你看到別的教程沒有以 / 結束,那麼多半是直接從Retrofit 1.X 照搬過來的。這就是一個固定的格式也沒什麼好多說的。
二、接下來就是接口定義了。首先看一下幾種請求的方法
這裏寫圖片描述
平時主要用到的也就是Get和Post,其它的瞭解一下就可以了。然後看一下在請求之中要是用的具體的參數:
這裏寫圖片描述
這裏就要根據對應的字段,來使用對應的參數,這就要在實踐中自己來摸索了。

public interface WeatherApi {
    @GET("?city=beijing")
    Call<ResponseBody> getWeather(@Header("apikey") String key);
}

在api的接口要求中可以看到要求上傳一個apikey的,而且是header類型的,所以這裏就@Header(“apikey”),括號裏面的內容都要看api的具體情況不是自己定義的。後面的String則是根據需要可以自由變換或者是自定義。下面說一下@Get中的地址拼接問題。

BaseUrl 註解中提供的值 最後結果
http://localhost:4567/path/to/other/ /post http://localhost:4567/post
http://localhost:4567/path/to/other/ post http://localhost:4567/path/to/other/post
http://localhost:4567/path/to/other/ https://github.com/CallMeSp https://github.com/CallMeSp

從上面不能難看出以下規則:
1.如果你在註解中提供的url是完整的url,則url將作爲請求的url。
2.如果你在註解中提供的url是不完整的url,且不以 / 開頭,則請求的url爲baseUrl+註解中提供的值
3.如果你在註解中提供的url是不完整的url,且以 / 開頭,則請求的url爲baseUrl的主機部分+註解中提供的值
所以我們上面拼接出來的地址就是http://apis.baidu.com/heweather/weather/free?city=beijing
接口也有了,實例也有了,接下來:
三、獲取api對象

WeatherApi weatherApi=weatherTry.create(WeatherApi.class);

其實呢就是將我們定義的接口和實例連接了起來,也是固定的格式。
四、獲取請求對象
還記得上面的interface中有個getWeather麼,那就是我們的具體的請求方法,第四步就是來調用這個方法了。

final Call<ResponseBody> call=weatherApi.getWeather("a79124c4594c2e5a0799a39ea8f64c87");

這樣利用一個Call類型,就完成了對請求方法的具體定義,ResponseBody是Retrofit中的默認返回類型。
五、發送請求
該定義的也都定義的,接下來就要發送請求了。我這裏用的是異步執行。

call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    Log.e("onResponse", "response=" + response.body().string());
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            @Override
            public void onFailure(Call<ResponseBody> call, Throwable throwable) {
            }
        });

這樣就發送了請求,而且在Log中打印了返回結果。
這裏寫圖片描述
就這樣完成了請求的發送以及接收數據。但這樣就結束了麼?這些數據是我們想要的格式麼?說好的Rxjava去哪了?我們接着看。下面我們就來重新走一遍流程,當然是用Rxjava了。

Retrofit zhuangRetrofit=new Retrofit.Builder()
                .client(new OkHttpClient())
                .baseUrl("http://www.zhuangbi.info/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

還是先創建實例
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

不一樣的是這裏多了 兩個add。這就是爲了要再Rxjava中轉換json的格式要添加的格式工廠了。先來看一下這個接口的返回數據的類型:
這裏寫圖片描述
我們決定來解析出來內容中的description字段和image_url字段。所以需要先自定義一個類

package com.sp.rerofittry;

public class ZhuangbiImage {
    public String description;
    public String image_url;
    public String file_size;
    public Upload upload;
}
class Upload{
    String id;
    String name;
    String description;
    String disk;
    String path;
    String size;
    String user_id;
    String created_at;
    String updated_at;
    String uploadable_id;
    String uploadable_type;
    String url;
}

然後看一下接口的創建。

public interface ZhuangbiApi {
    @GET("search")
    Observable<List<ZhuangbiImage>> search(@Query("q") String query);
}

這裏的Observable就是Rxjava的使用了,這裏充當的就是被觀察者的角色,後面會在Activity中創建觀察者,然後訂閱,就完成了之間的交互。

final ZhuangbiApi zhuangbiApi=zhuangRetrofit.create(ZhuangbiApi.class);
        zhuangbiApi .search("110")
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<List<ZhuangbiImage>>() {
                        @Override
                        public void onCompleted() {
                        }
                        @Override
                        public void onError(Throwable throwable) {
                        }
                        @Override
                        public void onNext(List<ZhuangbiImage> zhuangbiImages) {
                            for (int i=0;i<zhuangbiImages.size();i++){
                                Log.e("list",zhuangbiImages.get(i).image_url+"   "+zhuangbiImages.get(i).description);
                                Log.e("name",zhuangbiImages.get(i).upload.created_at);
                            }
                        }
                    });

要注意的是
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())

這裏在io線程中訂閱然後在主線程中返回結果,耗時的工作都不能放在主線程來實現。然後看一下返回結果
這裏寫圖片描述
就解析出了我們想要的部分。圖片的url以及標題。這就是Retrofit和Rxjava的簡單結合了。更多內容…敬請期待…
另外放出這個demo的github地址 https://github.com/CallMeSp/Retrofit-Rxjava_demo.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章