上一章节讲解了OkHttp
的基本使用,这节就来看看Retrofit
的基本使用
调用的网址如下:
public static final String RETROFIT_BASE_URL = "https://api.douban.com/";
public static final String POS_HTTP_WEATHER = "http://api.k780.com:88/";
public static final String URL_IMAGE_01 = "http://d.hiphotos.baidu.com/";
Retrofit
的单独使用
-
GET
中Query
的使用
@GET("/v2/book/search?")
Call<BookInfo> getDuBanDataUseQuery(@Query("q") String bookName, @Query("tag") String tag, @Query("start") int start, @Query("count") int count);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.RETROFIT_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Call<BookInfo> duBanDataCall = retrofitApi.getDuBanDataUseQuery("小王子", null, 0, 3);
duBanDataCall.enqueue(new Callback<BookInfo>() {
@Override
public void onResponse(Call<BookInfo> call, Response<BookInfo> response) {
if (response != null && response.body() != null) {
List<Book> results = response.body().getBooks();
for (Book book : results) {
Log.e("LHC", "bookTitle:" + book.getTitle() + ", bookAuthor:" + book.getAuthor()[0]);
}
}
}
@Override
public void onFailure(Call<BookInfo> call, Throwable t) {
ToastUtils.showShort("调用失败");
t.printStackTrace();
}
});
-
GET
中QueryMap
的使用
@GET("v2/book/search?")
Call<BookInfo> getDuBanDataUseQueryMap(@QueryMap Map<String, String> options);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.RETROFIT_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Map<String, String> options = new HashMap<>();
options.put("q", "小王子");
options.put("tag", "");
options.put("start", "0");
options.put("count", "3");
Call<BookInfo> duBanDataCall = retrofitApi.getDuBanDataUseQueryMap(options);
duBanDataCall.enqueue(new Callback<BookInfo>() {
@Override
public void onResponse(Call<BookInfo> call, Response<BookInfo> response) {
if (response != null && response.body() != null) {
List<Book> results = response.body().getBooks();
for (Book book : results) {
Log.e("LHC", "bookTitle:" + book.getTitle() + ", bookAuthor:" + book.getAuthor()[0]);
}
}
}
@Override
public void onFailure(Call<BookInfo> call, Throwable t) {
ToastUtils.showShort("调用失败");
t.printStackTrace();
}
});
-
GET
中Path
的使用
@GET("v2/book/{id}")
Call<Book> getDuBanDataUsePath(@Path("id") String id);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.RETROFIT_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Call<Book> duBanDataUsePathCall = retrofitApi.getDuBanDataUsePath("1003078");
duBanDataUsePathCall.enqueue(new Callback<Book>() {
@Override
public void onResponse(Call<Book> call, Response<Book> response) {
if (response != null && response.body() != null) {
Book book = response.body();
Log.e("LHC", "bookTitle:" + book.getTitle() + ", bookAuthor:" + book.getAuthor()[0]);
}
}
@Override
public void onFailure(Call<Book> call, Throwable t) {
ToastUtils.showShort("调用失败");
t.printStackTrace();
}
});
-
POST
中Field
的使用
@FormUrlEncoded
@POST("/?")
Call<Weathers> getWeathersData(@Field("app") String app, @Field("weaid") String weaId, @Field("appkey") String appKey, @Field("sign") String sign, @Field("format") String format);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.POS_HTTP_WEATHER)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Call<Weathers> weathersDataCall = retrofitApi.getWeathersData("weather.future", "1", "10003", "b59bc3ef6191eb9f747dd4e83c99f2a4", "json");
weathersDataCall.enqueue(new Callback<Weathers>() {
@Override
public void onResponse(Call<Weathers> call, Response<Weathers> response) {
if (response != null && response.body() != null) {
List<WeatherInfo> results = response.body().getResult();
for (WeatherInfo weatherInfo : results) {
Log.e("LHC", "cityName:" + weatherInfo.getCitynm() + ", days:" + weatherInfo.getDays() + ", temperature:" + weatherInfo.getTemperature());
}
}
}
@Override
public void onFailure(Call<Weathers> call, Throwable t) {
ToastUtils.showShort("调用失败");
}
});
-
POST
中FieldMap
的使用
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.POS_HTTP_WEATHER)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Map<String, String> options = new HashMap<>();
options.put("app", "weather.future");
options.put("weaid", "1");
options.put("appkey", "10003");
options.put("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4");
options.put("format", "json");
Call<Weathers> weathersDataCall = retrofitApi.getWeathersData(options);
weathersDataCall.enqueue(new Callback<Weathers>() {
@Override
public void onResponse(Call<Weathers> call, Response<Weathers> response) {
if (response != null && response.body() != null) {
List<WeatherInfo> results = response.body().getResult();
for (WeatherInfo weatherInfo : results) {
Log.e("LHC", "cityName:" + weatherInfo.getCitynm() + ", days:" + weatherInfo.getDays() + ", temperature:" + weatherInfo.getTemperature());
}
}
}
@Override
public void onFailure(Call<Weathers> call, Throwable t) {
ToastUtils.showShort("调用失败");
}
});
-
POST
中Body
的使用
//没有调用成功
- 下载文件
@Streaming
@GET("zhidao/pic/item/0bd162d9f2d3572c5a387f618c13632763d0c3b1.jpg")
Call<ResponseBody> downFile();
private String FILE_DIR = Environment.getExternalStorageDirectory() + File.separator + "downImage";
private String FILE_NAME = "ok_" + System.currentTimeMillis() + ".jpg";
private void downLoadImage() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.URL_IMAGE_01)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Call<ResponseBody> call = retrofitApi.downFile();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) {
if (response != null && response.body() != null) {
ThreadUtil.getInstance().getExecutorService().execute(new Runnable() {
@Override
public void run() {
writeFileToDisk(response);
}
});
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
}
private void writeFileToDisk(Response<ResponseBody> response) {
InputStream is = null;
FileOutputStream fos = null;
try {
byte[] buff = new byte[2048];
is = response.body().byteStream();
File filePath = new File(FILE_DIR);
if (!filePath.mkdirs()) {
filePath.createNewFile();
}
final File file = new File(filePath, FILE_NAME);
fos = new FileOutputStream(file);
int len = 0;
while ((len = is.read(buff)) != -1) {
fos.write(buff, 0, len);
}
mHandler.post(new Runnable() {
@Override
public void run() {
Glide.with(RetrofitMainActivity.this).load(file.getAbsoluteFile()).into(ivShow);
}
});
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- 上传文件
@Multipart
@POST("xxx/uploadImage")
Call<FileBean> upLoadMultiFile1(@Part MultipartBody.Part[] parts);
private void upLoadMultiFile1() {
List<File> files = getFiles();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.URL_UPLOAD_BASE)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
MultipartBody.Part[] parts = new MultipartBody.Part[files.size()];
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part filePart = MultipartBody.Part.createFormData(file.getName(), requestFile);
parts[i] = filePart;
}
Call<FileBean> fileBeanCall = retrofitApi.upLoadMultiFile1("files", parts);
fileBeanCall.enqueue(new Callback<FileBean>() {
@Override
public void onResponse(Call<FileBean> call, Response<FileBean> response) {
List<String> result = response.body().getResult();
for (String s : result) {
Log.e("LHC", "imgUrl:\n"+ s);
}
}
@Override
public void onFailure(Call<FileBean> call, Throwable t) {
t.printStackTrace();
}
});
}
private List<File> getFiles() {
List<File> files = new ArrayList<>();
files.add(new File(Environment.getExternalStorageDirectory()+File.separator+"crop_image.jpg"));
files.add(new File(Environment.getExternalStorageDirectory()+File.separator+"temp.png"));
return files;
}
Retrofit+RxJava
联合使用
-
GET
中QueryMap
的使用
@GET("v2/book/search?")
Observable<BookInfo> getDuBanDataUseQueryMap1(@QueryMap Map<String, String> options);
private void getQueryMap() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.RETROFIT_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Map<String, String> options = new HashMap<>();
options.put("q", "小王子");
options.put("tag", "");
options.put("start", "0");
options.put("count", "3");
Observable<BookInfo> duBanDataUseQueryMap = retrofitApi.getDuBanDataUseQueryMap1(options);
duBanDataUseQueryMap.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io()).subscribe(new Observer<BookInfo>() {
@Override
public void onCompleted() {
ToastUtils.showShort("调用成功");
}
@Override
public void onError(Throwable e) {
ToastUtils.showShort("调用失败");
e.printStackTrace();
}
@Override
public void onNext(BookInfo bookInfo) {
List<Book> results = bookInfo.getBooks();
for (Book book : results) {
Log.e("LHC", "bookTitle:" + book.getTitle() + ", bookAuthor:" + book.getAuthor()[0]);
}
}
});
}
-
POST
中FieldMap
的使用
@FormUrlEncoded
@POST("/?")
Observable<Weathers> getWeathersData1(@FieldMap Map<String, String> options);
private void postFieldMap() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.POS_HTTP_WEATHER)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Map<String, String> options = new HashMap<>();
options.put("app", "weather.future");
options.put("weaid", "1");
options.put("appkey", "10003");
options.put("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4");
options.put("format", "json");
Observable<Weathers> duBanDataUseQueryMap = retrofitApi.getWeathersData1(options);
duBanDataUseQueryMap.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io()).subscribe(new Observer<Weathers>() {
@Override
public void onCompleted() {
ToastUtils.showShort("调用成功");
}
@Override
public void onError(Throwable e) {
ToastUtils.showShort("调用失败");
e.printStackTrace();
}
@Override
public void onNext(Weathers bookInfo) {
List<WeatherInfo> results = bookInfo.getResult();
for (WeatherInfo weatherInfo : results) {
Log.e("LHC", "cityName:" + weatherInfo.getCitynm() + ", days:" + weatherInfo.getDays() + ", temperature:" + weatherInfo.getTemperature());
}
}
});
}
- 下载文件
// @Streaming //单独使用`Retrofit`时,加上此参数并没有报错,但是和`RxJava`联合起来使用时,会出现错误
@GET("zhidao/pic/item/0bd162d9f2d3572c5a387f618c13632763d0c3b1.jpg")
Observable<ResponseBody> downFile1();
private String FILE_DIR = Environment.getExternalStorageDirectory() + File.separator + "downImage";
private String FILE_NAME = "ok_" + System.currentTimeMillis() + ".jpg";
private void downImage() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtils.URL_IMAGE_01)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
Observable<ResponseBody> observable = retrofitApi.downFile1();
observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onCompleted() {
Log.e("LHC", "下载成功");
}
@Override
public void onError(Throwable e) {
Log.e("LHC", "下载失败");
e.printStackTrace();
}
@Override
public void onNext(final ResponseBody responseBody) {
mHandler = ThreadUtil.getInstance().getHandler();
ThreadUtil.getInstance().getExecutorService().execute(new Runnable() {
@Override
public void run() {
writeFileToDisk(responseBody);//
}
});
}
});
}
从上面可以看到,Retrofit
和Retrofit+RxJava
的使用差不多,不用在与接口返回值和回调方法。所以这里就只列举这几个。
Retrofit+RxJava
的简单封装
public class RetrofitUtils {
private static RetrofitUtils mRetrofitUtils;
private Retrofit mRetrofit;
private String FILE_DIR = Environment.getExternalStorageDirectory() + File.separator + "downImage";
private String FILE_NAME = "ok_" + System.currentTimeMillis() + ".jpg";
public static RetrofitUtils getInstance(){
if (mRetrofitUtils == null){
synchronized (RetrofitUtils.class){
if (mRetrofitUtils == null){
mRetrofitUtils = new RetrofitUtils();
}
}
}
return mRetrofitUtils;
}
public <T>T getRetrofitApi(Class<T> cls, String baseUrl){
return getRetrofit(baseUrl).create(cls);
}
private Retrofit getRetrofit(String baseUrl){
if (mRetrofit == null){
mRetrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return mRetrofit;
}
public <T> void init(Observable<T> observable, Subscriber<T> subScribe){
observable
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(subScribe);
}
public <T> void init(Observable<T> observable, ApiCallback<T> callback){
observable
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(getSubscriber(callback));
}
private <T> Subscriber<T> getSubscriber(final ApiCallback<T> callback){
return new Subscriber<T>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
callback.onError("调用失败");
e.printStackTrace();
}
@Override
public void onNext(T t) {
callback.onSuccess(t);
}
};
}
public void writeFileToDisk(ResponseBody response, DownloadCallback callback) {
InputStream is = null;
FileOutputStream fos = null;
try {
byte[] buff = new byte[2048];
is = response.byteStream();
File filePath = new File(FILE_DIR);
if (!filePath.exists()) {
filePath.mkdirs();
}
final File file = new File(filePath, FILE_NAME);
fos = new FileOutputStream(file);
int len = 0;
while ((len = is.read(buff)) != -1) {
fos.write(buff, 0, len);
}
callback.getImageFile(file.getAbsolutePath());
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public interface ApiCallback<T>{
void onSuccess(T t);
void onError(String msg);
}
public interface DownloadCallback{
void getImageFile(String imgFile);
}
}
-
GET
中QueryMap
的使用
Map<String, String> options = new HashMap<>();
options.put("q", "小王子");
options.put("tag", "");
options.put("start", "0");
options.put("count", "3");
mRetrofitUtils.init(mRetrofitUtils.getRetrofitApi(RetrofitApi.class, UrlUtils.RETROFIT_BASE_URL).getDuBanDataUseQueryMap1(options), new Subscriber<BookInfo>() {
@Override
public void onCompleted() {
ToastUtils.showShort("调用成功");
}
@Override
public void onError(Throwable e) {
ToastUtils.showShort("调用失败");
e.printStackTrace();
}
@Override
public void onNext(BookInfo bookInfo) {
List<Book> results = bookInfo.getBooks();
for (Book book : results) {
Log.e("LHC", "bookTitle:" + book.getTitle() + ", bookAuthor:" + book.getAuthor()[0]);
}
}
});
-
POST
中FieldMap
的使用
Map<String, String> map = new HashMap<>();
map.put("app", "weather.future");
map.put("weaid", "1");
map.put("appkey", "10003");
map.put("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4");
map.put("format", "json");
mRetrofitUtils.init(mRetrofitUtils.getRetrofitApi(RetrofitApi.class, UrlUtils.POS_HTTP_WEATHER).getWeathersData1(map), new RetrofitUtils.ApiCallback<Weathers>() {
@Override
public void onSuccess(Weathers weathers) {
List<WeatherInfo> results = weathers.getResult();
for (WeatherInfo weatherInfo : results) {
Log.e("LHC", "cityName:" + weatherInfo.getCitynm() + ", days:" + weatherInfo.getDays() + ", temperature:" + weatherInfo.getTemperature());
}
}
@Override
public void onError(String msg) {
ToastUtils.showShort(msg);
}
});
- 下载文件
mRetrofitUtils.init(mRetrofitUtils.getRetrofitApi(RetrofitApi.class, UrlUtils.URL_IMAGE_01).downFile1(), new RetrofitUtils.ApiCallback<ResponseBody>() {
@Override
public void onSuccess(final ResponseBody responseBody) {
ThreadUtil.getInstance().getExecutorService().execute(new Runnable() {
@Override
public void run() {
mRetrofitUtils.writeFileToDisk(responseBody, new RetrofitUtils.DownloadCallback() {
@Override
public void getImageFile(final String imgFile) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Glide.with(RetrofitRxJavaFZActivity.this).load(imgFile).into(ivShow);
}
});
}
});
}
});
}
@Override
public void onError(String msg) {
ToastUtils.showShort(msg);
}
});
- 上传文件
@Multipart
@POST("xxx/uploadImage")
Observable<FileBean> upLoadMultiFile2(@Part MultipartBody.Part[] parts);
File file = new File(Environment.getExternalStorageDirectory()+File.separator+"crop_image.jpg");
File file1 = new File(Environment.getExternalStorageDirectory()+File.separator+"temp.png");
List<File> files = new ArrayList<>();
files.add(file);
files.add(file1);
MultipartBody.Part[] parts = new MultipartBody.Part[files.size()];
for (int i = 0; i < files.size(); i++) {
File fileItem = files.get(i);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), fileItem);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("files", fileItem.getName(), requestFile);
parts[i] = filePart;
}
mRetrofitUtils.init(mRetrofitUtils.getRetrofitApi(RetrofitApi.class, UrlUtils.URL_UPLOAD_BASE).upLoadMultiFile2(parts), new RetrofitUtils.ApiCallback<FileBean>() {
@Override
public void onSuccess(FileBean bean) {
Log.e("LHC", "imgUrl:\n"+ bean.getResult().get(0)+"\n"+bean.getResult().get(1));
}
@Override
public void onError(String msg) {
ToastUtils.showShort("上传失败");
}
});
这样Retrofit
基本使用就完成了。
OKGO
是对Retrofit
的再次封装,使用很方便,地址:https://github.com/jeasonlzy/okhttp-OkGo