Retrofit2.0 學(xué)習(xí)小記

Retrofit2.0 學(xué)習(xí)小記

來自官網(wǎng)的介紹:Retrofit turns your HTTP API into Java interface.Retrofit把HTTP API變成Java的接口。

1.基本用法

直接上代碼:比如我們使用豆瓣電影的Top250做測試鏈接,目標(biāo)地址為:https://api.douban.com/v2/movie/top250?start=0&count=10
導(dǎo)包:compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
首先要建這樣一個(gè)接口:
public interface MovieService{
@GET("top250")
Call<MovieEntity> getTopMovie(@Query("start")int start,@Query("count") int count);
}
然后你還需要?jiǎng)?chuàng)建一個(gè)Retrofit對象:
public static final String baseUrl="https://api.douban.com/v2/movie/";
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
再用這個(gè)Retrofit對象創(chuàng)建一個(gè)MovieService對象:
MovieService movieService=retrofit.create(MovieService.class);
Call<MovieEntity> call=movieService.getTopMovie(0,10);
//call.enqueue()異步請求,call.execute()同步請求
call.enqueue(new Callback<MovieEntity>(){
@Override
public void onResponse(Call<MovieEntity> call, Response<MovieEntity> response) {
result_TV.setText(response.body().toString());
}
@Override
public void onFailure(Call<MovieEntity> call, Throwable t) {
result_TV.setText(t.getMessage());
}
});
在這邊還可以移除一個(gè)請求:
Retrofit 1.x版本沒有直接取消正在進(jìn)行中任務(wù)的方法的,在2.x的版本中,Service的模式變成Call的形式的原因是為了讓正在進(jìn)行的事務(wù)可以被取消。要做到這點(diǎn),只需要調(diào)用call.cancel()。
以上就是Retrofit2.0的基本用法了,下面講講它的詳細(xì)用法:

1.關(guān)于各種網(wǎng)絡(luò)請求的service

下面分為GET、POST、DELETE和PUT的請求,說明@Path、@Query、@QueryMap、@Body、@Filed的用法。

GET

1.一個(gè)簡單的get請求:
http://102.10.10.132/api/News
@GET("News") Call<NewsBean> getItem();
2.URL中帶有參數(shù):http://102.10.10.132/api/News/{資訊id}
@GET("News/{newsId}")
Call<NewsBean> getItem(@Path("newsId") String newsId);
3.參數(shù)在URL問號之后:http://102.10.10.132/api/News?newsId={資訊id}
@GET("News")
Call<NewsBean> getItem(@Query("newsId") String newsId);
或者帶有兩個(gè)參數(shù):http://102.10.10.132/api/News?newsId={資訊id}&type={類型}
@GET("News")
Call<NewsBean> getItem(@Query("newsId") String newsId,@Query("type") type);
4.多個(gè)參數(shù)在URL問號之后,且個(gè)數(shù)不確定:
http://102.10.10.132/api/News?newsId={資訊id}&type={類型}...
@GET("News")
Call<NewsBean> getItem(@QueryMap Map<String, String> map);

POST

1.需要補(bǔ)全URL,post的數(shù)據(jù)只有一條reason:
http://102.10.10.132/api/Comments/{newsId}
@FormUrlEncoded
@POST("Comments/{newsId}")
Call<Comment> reportComment(@Path("newsId") String commentId,@Field("reason") String reason);
2.需要補(bǔ)全URL,問號后加入access_token,post的數(shù)據(jù)只有一條reason:
http://102.10.10.132/api/Comments/{newsId}?access_token={access_token}
@FormUrlEncoded
@POST("Comment/{newsId}")
Call<Comment> reportComment(@Path("newsId") String commentId,@Query("access_token") String access_token,@Field("reason") String reason);
3.需要補(bǔ)全URL,問號后加入access_token,post一個(gè)body(對象):
http://102.10.10.132/api/Comments/{newsId}?access_token={access_token}
@FormUrlEncoded
@POST("Comment/{newsId}")
Call<Comment> reportComment(@Path("newsId") String commentId,@Query("access_token") String access_token,@Body CommentBean bean);
關(guān)于DELETE和PUT方式由于使用較少,這里就不舉例了,可自行g(shù)oogle
總結(jié)
@Path:URL問號之前的參數(shù)
@Query:URL問號后面的參數(shù)
@QueryMap:相當(dāng)于多個(gè)@Query
@Field:用于POST請求,提交單個(gè)數(shù)據(jù)
@Body:相當(dāng)于多個(gè)@Field,以對象的形式提交
若需要重新定義接口地址,可以使用@Url,例如:
@GET
Call<MovieEntity> getTopMovie(@Url String url,@Query("start")int start,@Query("count") int count);

關(guān)于解析

在Retrofit2.0中,Converter不再包含在packeage中了,需要自己添加Converter,不然的話Retrofit只能接收字符串結(jié)果。同樣的,Retrofit也不再依賴于Gson,如果你想接收json結(jié)果并解析成DAO,你必須把GsonConverter作為一個(gè)獨(dú)立的依賴添加進(jìn)來:compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' ,然后使用addConverterFactory(GsonConverterFactory.create())幫他添加進(jìn)來。
官方Converter modules列表
Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf:com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml
當(dāng)然也可以通過實(shí)現(xiàn)Converter.Factory接口來創(chuàng)建一個(gè)自定義的converter。

2.Retrofit+RxJava(附上demo)

導(dǎo)包:
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'io.reactivex:rxandroid:1.1.0'
在創(chuàng)建Retrofit的過程添加以下代碼:
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create())
//結(jié)合RxJava .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
這樣一來我們定義的Service返回值就不再是一個(gè)Call了,而是一個(gè)Observable,重新定義MovieService:
public interface MovieService {
@GET("top250")
Observable<MovieEntity> getTopMovie(@Query("start") int start, @Query("count") int count);
}
在網(wǎng)絡(luò)請求方法中改為:
//進(jìn)行網(wǎng)絡(luò)請求
private void getMovie(){

Retrofit retrofit = <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">new</span></span> Retrofit.Builder()
        .baseUrl(baseUrl)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();

MovieService movieService = retrofit.create(MovieService.class);

movieService.getTopMovie(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-number"</span>><span class="hljs-number">0</span></span>, <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-number"</span>><span class="hljs-number">10</span></span>)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">new</span></span> Subscriber<MovieEntity>() {
            <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-annotation"</span>>@Override</span>
            <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-function"</span>><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">public</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">void</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title"</span>>onCompleted</span><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>>()</span> </span>{
                Toast.makeText(MainActivity.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">this</span></span>, <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>><span class="hljs-string">"Get Top Movie Completed"</span></span>, Toast.LENGTH_SHORT).show();
            }

            <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-annotation"</span>>@Override</span>
            <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-function"</span>><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">public</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">void</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title"</span>>onError</span><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>>(Throwable e)</span> </span>{
                resultTV.setText(e.getMessage());
            }

            <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-annotation"</span>>@Override</span>
            <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-function"</span>><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">public</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">void</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title"</span>>onNext</span><span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>>(MovieEntity movieEntity)</span> </span>{
                resultTV.setText(movieEntity.toString());
            }
        });

}
這就基本上完成了Retrofit和RxJava的結(jié)合,但是可以把創(chuàng)建Retrofit的過程封裝一下。可參考這篇文章,不錯(cuò)的一個(gè)例子

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

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

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