Retrofit基本使用
內(nèi)容
- 基礎(chǔ)
- 接口配置
- 發(fā)送請求
- 異步請求 && 示例一
- Convert && 示例二
- RxJava支持 && 示例三
- 參考:Retrofit官網(wǎng)
基礎(chǔ)
使用Retrofit能夠通過添加注解秤茅,輕松地將 HTTP API 轉(zhuǎn)化為 Java 接口天通,示例如下:
compile 'com.squareup.okhttp3:okhttp:3.8.1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
使用上述接口:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
調(diào)用 call 的 execute 方法或者 enqueue 方法進行同步或者異步的網(wǎng)絡(luò)請求:
Call<List<Repo>> repos = service.listRepos("octocat");
repos.execute() //同步調(diào)用
repos.enqueue(new Callback<T>() {...}) //異步調(diào)用
接口配置
- 使用 @GET, @POST, @PUT, @DELETE, @HEAD 注解來相應(yīng)標(biāo)注 HTTP API 的請求類型
- 使用@Path楣黍、@Query 注解標(biāo)注 api url 中的參數(shù)
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
- 復(fù)雜結(jié)構(gòu)的參數(shù)使用 @QueryMap 來標(biāo)注
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
- 使用@Body注解 可以將 Java 對象標(biāo)注為請求體
@POST("users/new")
Call<User> createUser(@Body User user);
- 其他注解:
- @FormUrlEncoded
- @Multipart
- @Headers
示例一
使用Gank.io的隨機數(shù)據(jù)接口,實現(xiàn)如下簡單的示例:
GankService.java
public interface GankService {
// http://gank.io/api/random/data/分類/個數(shù)
@GET("random/data/{category}/{number}")
Call<ResponseBody> getResponseData(@Path("category") String category, @Path("number") String number);
}
GankActivity.java
public class GankActivity extends AppCompatActivity {
TextView tvGank;
final String pageSize = "10";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gank);
findViewById(R.id.btn_gank).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getData();
}
});
tvGank = (TextView) findViewById(R.id.tv_gank);
}
private void getData() {
// BaseUrl 需要以 '/' (slash)結(jié)尾
final String baseUrl = "http://gank.io/api/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.build();
GankService service = retrofit.create(GankService.class);
Call<ResponseBody> call = service.getResponseData("Android", pageSize);
// call.execute(); // 同步調(diào)用
// call.enqueue(); // 異步調(diào)用
// call.cancel(); // 取消請求
// call.isCanceled(); // 是否請求
// call.isExecuted(); // 是否調(diào)用
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
tvGank.setText(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("corey", "call.enqueue failed:" + t.toString());
}
});
}
}
Converter
- 默認地,若不做 converter 相關(guān)配置,Retrofit只能將網(wǎng)絡(luò)請求的 HTTP body 轉(zhuǎn)化為 OkHttp 中的 ResponseBody 類型,@Body中接收參數(shù)也只能接收 ResponseBody 類型
- Retrofit 提供了多種解析庫的converter,只需在build時添加配置即可使用岂傲,例如,要添加支持Gson解析庫從而支持對Json的解析子檀,只需如下:
compile 'com.google.code.gson:gson:2.8.1'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
- 除了Retrofit內(nèi)置支持的各個解析庫外镊掖,還可以添加自定義的解析庫。新建一個類繼承自 Converter.Factory 褂痰,然后在初始化Retrofit示例時亩进,將該自定義的Converter傳入即可。
示例二
GankService.java
public interface GankService {
// http://gank.io/api/random/data/分類/個數(shù)
@GET("random/data/{category}/{number}")
Call<GankRandom> getEntityData(@Path("category") String category, @Path("number") String number);
}
GankActivity2.java
public class GankActivity2 extends AppCompatActivity {
TextView tvGank;
RecyclerView rvGank;
SimpleStringAdapter simpleStringAdapter;
ProgressDialog progressDialog;
final String pageSize = "10";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gank2);
findViewById(R.id.btn_gank2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getData();
}
});
tvGank = (TextView) findViewById(R.id.tv_gank2);
rvGank = (RecyclerView) findViewById(R.id.rv_gank2);
rvGank.setLayoutManager(new LinearLayoutManager(this));
simpleStringAdapter = new SimpleStringAdapter(this);
rvGank.setAdapter(simpleStringAdapter);
progressDialog = new ProgressDialog(this);
}
private void getData() {
progressDialog.show();
final String baseUrl = "http://gank.io/api/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
GankService service = retrofit.create(GankService.class);
Call<GankRandom> call = service.getEntityData("Android", pageSize);
call.enqueue(new Callback<GankRandom>() {
@Override
public void onResponse(Call<GankRandom> call, Response<GankRandom> response) {
List<String> data = new ArrayList<String>();
for (GankRandom.ResultsBean bean : response.body().getResults()) {
data.add(bean.getDesc());
}
simpleStringAdapter.setStrings(data);
progressDialog.dismiss();
}
@Override
public void onFailure(Call<GankRandom> call, Throwable t) {
Log.d("corey", "call.enqueue failed:" + t.toString());
progressDialog.dismiss();
}
});
}
}
Retrofit + RxJava
- Retrofit可以配合RxJava使用缩歪,具體的使用如下:
- 定義接口時归薛,將其返回值設(shè)為Observable
- 新建Retrofit實例時,添加RxJava支持
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.9'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
interface GitHubService {
@GET("users/{user}/repos")
Observable<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
service.listRepos("google")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Repo>>(){...})
示例三
GankService.java
public interface GankService {
// http://gank.io/api/random/data/分類/個數(shù)
@GET("random/data/{category}/{number}")
Observable<GankRandom> getObservableData(@Path("category") String category, @Path("number") String number);
}
GankActivity3.java
public class GankActivity3 extends AppCompatActivity {
TextView tvGank;
RecyclerView rvGank;
SimpleStringAdapter simpleStringAdapter;
Disposable disposable;
ProgressDialog progressDialog;
final String pageSize = "10";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gank3);
findViewById(R.id.btn_gank3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getData();
}
});
tvGank = (TextView) findViewById(R.id.tv_gank3);
rvGank = (RecyclerView) findViewById(R.id.rv_gank3);
rvGank.setLayoutManager(new LinearLayoutManager(this));
simpleStringAdapter = new SimpleStringAdapter(this);
rvGank.setAdapter(simpleStringAdapter);
progressDialog = new ProgressDialog(this);
}
private void getData() {
final String baseUrl = "http://gank.io/api/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
GankService service = retrofit.create(GankService.class);
disposable = service.getObservableData("Android", pageSize)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Function<GankRandom, List<String>>() {
@Override
public List<String> apply(@NonNull GankRandom gankRandom) throws Exception {
List<String> toReturn = new ArrayList<>();
for (GankRandom.ResultsBean gankBean : gankRandom.getResults()) {
toReturn.add(gankBean.getDesc());
}
return toReturn;
}
})
.subscribeWith(
new DisposableObserver<List<String>>() {
@Override
protected void onStart() {
progressDialog.show();
}
@Override
public void onNext(@NonNull List<String> titles) {
progressDialog.dismiss();
simpleStringAdapter.setStrings(titles);
}
@Override
public void onError(@NonNull Throwable e) {
progressDialog.dismiss();
}
@Override
public void onComplete() {
}
}
);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (!disposable.isDisposed()) {
disposable.dispose();
}
}
}