新手入門的時候原理性的東西太多容易迷糊,反倒效果不好瑞眼,廢話不多說:
以下示例通過 http://ip.taobao.com/service/getIpInfo.php?ip=21.22.11.33 獲取json數(shù)據(jù)。
完整代碼地址:https://github.com/hibernate3/RetrofitDemo
環(huán)境:JDK 1.8棵逊,AndroidStudio 2.2.3
1伤疙、通過配置gradle配置將Retrofit框架引入項目
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
2、編寫API服務(wù)代碼
package com.example.retrofitdemo.data.api;
import com.example.retrofitdemo.data.api.response.GetIpInfoResponse;
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;
import rx.Observable;
/**
* Created by Steven on 16/12/16.
*/
public interface ApiService {
@GET("service/getIpInfo.php")
Observable<GetIpInfoResponse> getIpInfo(@Query("ip") String ip);//使用RxJava
// @GET("service/getIpInfo.php")
// Call<GetIpInfoResponse> getIpInfo(@Query("ip") String ip);//不使用RxJava
}
3、定義接收數(shù)據(jù)的response
package com.example.retrofitdemo.data.api.response;
import com.example.retrofitdemo.data.api.model.IpInfo;
/**
* Created by Steven on 16/12/16.
*/
public class GetIpInfoResponse {
public IpInfo data;
}
4徒像、請求數(shù)據(jù)并顯示
package com.example.retrofitdemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.example.retrofitdemo.data.api.ApiService;
import com.example.retrofitdemo.data.api.response.GetIpInfoResponse;
import retrofit.Call;
import retrofit.Callback;
import retrofit.GsonConverterFactory;
import retrofit.Response;
import retrofit.Retrofit;
import retrofit.RxJavaCallAdapterFactory;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import rx.Subscriber;
public class MainActivity extends Activity {
private static final String ENDPOINT = "http://ip.taobao.com";
private TextView mTvContent;
private ProgressBar mProgressBar;
private Button mButton;
private Subscription mSubscription;//用于取消訂閱
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvContent = (TextView) findViewById(R.id.tv_content);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mButton = (Button) findViewById(R.id.button_start);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTvContent.setText("");
mProgressBar.setVisibility(View.VISIBLE);
//=======使用RxJava=======
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
ApiService apiService = retrofit.create(ApiService.class);
mSubscription = apiService.getIpInfo("63.223.108.42")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<GetIpInfoResponse>() {
@Override
public void onCompleted() {
mProgressBar.setVisibility(View.GONE);
}
@Override
public void onError(Throwable e) {
mProgressBar.setVisibility(View.GONE);
mTvContent.setText(e.getMessage());
}
@Override
public void onNext(GetIpInfoResponse getIpInfoResponse) {
mTvContent.setText(getIpInfoResponse.data.country);
}
});
//=======不使用RxJava=======
// Retrofit retrofit = new Retrofit.Builder()
// .baseUrl(ENDPOINT)
// .addConverterFactory(GsonConverterFactory.create())
// .build();
//
// ApiService apiService = retrofit.create(ApiService.class);
//
// Call<GetIpInfoResponse> call = apiService.getIpInfo("63.223.108.42");
// call.enqueue(new Callback<GetIpInfoResponse>() {
// @Override
// public void onResponse(Response<GetIpInfoResponse> response, Retrofit retrofit) {
// mProgressBar.setVisibility(View.GONE);
// GetIpInfoResponse getIpInfoResponse = response.body();
// mTvContent.setText(getIpInfoResponse.data.country);
// }
//
// @Override
// public void onFailure(Throwable t) {
// mProgressBar.setVisibility(View.GONE);
// mTvContent.setText(t.getMessage());
// }
// });
}
});
}
@Override
protected void onDestroy() {
//使用RxJava方式時黍特,需要取消訂閱
if (mSubscription != null && mSubscription.isUnsubscribed()){
mSubscription.unsubscribe();
}
}
}
5、取消訂閱
正常情況下, 行為結(jié)束之后, 到達(dá)onComplete()或者onError(), RxJava的訂閱會自動取消锯蛀。但是在處理網(wǎng)絡(luò)請求的時候, 很可能會出現(xiàn)請求還沒有返回, 界面就已經(jīng)結(jié)束了的情況灭衷。
訂閱方法subscribe()的返回值是一個Subscription對象, 我們保存了這個對象的引用, 然后在onPause()或者onDestroy()的時候取消請求, 防止內(nèi)存泄露。
關(guān)于請求注解
Retrofit提供的請求方式注解有@GET和@POST旁涤,參數(shù)注解有@PATH和@Query等翔曲,我們只介紹常用的;前兩個顧名思義就是定義你的請求方式Get or Post,后面的@PATH指的是通過參數(shù)填充完整的路徑劈愚,一般用法:
@GET("{name}")Call<User> getUser(@Path("name") String username);
這里的參數(shù)username會被填充至{name}中瞳遍,形成完整的Url請求地址,{name}相當(dāng)于一個占位符造虎;
@Query就是我們的請求的鍵值對的設(shè)置傅蹂,我們構(gòu)建Call對象的時候會傳入此參數(shù)纷闺,
@POST("mobileLogin/submit.html")
Call<String> getString(@Query("loginname") String loginname,@Query("loginpwd") String loginpwd);
這里@Query("loginname")就是鍵算凿,后面的loginname就是具體的值了,值得注意的是Get和Post請求犁功,都是這樣填充參數(shù)的
同步和異步
這里注意用Retrofit請求的返回值是Call<T>或者Observable<T>(RxJava的情形)氓轰,泛型T是model類型,它有兩個方法:
execute()是同步方法, 返回Response<T>
enqueue()是異步方法, 在上面的例子中用的就是這個浸卦,在回調(diào)onResponse()中返回了Response<T>
Converter
Converter的作用:如果不指定Converter署鸡,默認(rèn)情況下Retrofit只能返回ResponseBody類型,加了Converter之后就可以返回我們定義的Model類型了限嫌。所以Converter替我們做了json -> model的工作靴庆。
本例子中ConverterFactory指定的是GsonConverterFactory。這里我們選的是Gson Converter怒医,所以依賴的是com.squareup.retrofit2:converter-gson炉抒。
Retrofit支持多種converters:
Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
用RxJava進(jìn)行線程切換
例子中.subscribeOn(Schedulers.io())指定Observable的工作, 在我們的例子中Observable的工作即發(fā)送請求,在io線程做稚叹,指定了被觀察者的處理線程焰薄;
.observeOn(AndroidSchedulers.mainThread())指定最后onNext()回調(diào)在主線程,即指定了通知后續(xù)觀察者的線程扒袖。
關(guān)于這兩個操作符的更多說明請看官方文檔:subscribeOn和observeOn塞茅。
轉(zhuǎn)載請說明出處:http://www.reibang.com/p/951996181289
參考鏈接:
http://blog.csdn.net/bitian123/article/details/51899716
http://blog.csdn.net/liuhongwei123888/article/details/50375283
http://www.cnblogs.com/mengdd/p/6047948.html