- 1、解析固定格式的json
- 2、添加 上传/下载 文件 进度回调
- 3、统一错误处理,log,cache 等
通常服务器接口返回的都是固定的json 如下 data 里面才是 正真的实体类,
{
"code": int, //请求返回状态码 0表示成功
"msg":String, // 存放错误信息
"data": {} || "data": []
}
对于这种数据类型 本框架 提供两种 解决方案
代码片段如下
@Override
public T convert( ResponseBody value) throws IOException {
try {
String result = value.string();
JSONObject response = new JSONObject(result);
int code = response.optInt("code");
if (ErrorType.SUCCESS==code) {
// return adapter.fromJson(result);
return adapter.fromJson(response.getString("data"));//解析data数据
}else {
String message = response.optString("msg", "");
throw new ServerException(code, message);
}
} catch (JSONException e) {
throw new ServerException(-1, "JSON解析异常");
}
}
这种方法 就不用每次建立实体 都不用在最外层再套一个 实体 下面是例子
public class User {
/**
* nickName : 用户001
* sex : 0
*/
private String nickName;
private int sex;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
public interface ApiService {
@GET("http://zzuli.gitee.io/api/user.html")
Observable<User> getUser();
@GET("http://zzuli.gitee.io/api/user.html")
Observable<DataNull> getUserNull();
@GET("http://zzuli.gitee.io/api/user.html")
Observable<String> getUserString();
@GET("http://zzuli.gitee.io/api/user.html")
Observable<Response<User>> getUserResponse();
@GET("http://zzuli.gitee.io/api/userlist.html")
Observable<List<User>> getUserList();
@Multipart
@POST
Observable<String> uploadFile(@Url String uploadUrl, @Part List<MultipartBody.Part> partList);
@Streaming
@GET
Observable<ResponseBody> downloadFile(@Url String fileUrl);
}
RetrofitClient
.newRetrofit()
.showLog(true)
.createApiService(ApiService.class)
.getUser()
.compose(Transformer.<User>switchSchedulers(loading_dialog))
.subscribe(new BaseObserver<User>() {
@Override
public void onError(ApiException exception) {
responseTv.setText("onError-->"+exception.code+ "-->"+exception.message);
loading_dialog.dismiss();
}
@Override
public void onSuccess(User user) {
responseTv.setText(user.getNickName());
loading_dialog.dismiss();
}
});
我们的User 就是data 里面的数据,完全不用在建立一个Response类包裹着User
public class DefaultTransformer<T> implements ObservableTransformer<Response<T>, T> {
@Override
public ObservableSource<T> apply(@NonNull Observable<Response<T>> upstream) {
return upstream
.subscribeOn(Schedulers.io())
.map(new Function<Response<T>, T>() {
@Override
public T apply(@NonNull Response<T> response) throws Exception {
return response.getData();
}
})
.observeOn(AndroidSchedulers.mainThread());
}
}
RetrofitClient
.getApiService(ApiService.class)
.getUserResponse()
.compose(new DefaultTransformer<User>())
.subscribe(new BaseObserver<User>() {
@Override
public void onError(ApiException exception) {
responseTv.setText("onError"+exception.message+exception.code);
loading_dialog.dismiss();
}
@Override
public void onSuccess(User user) {
responseTv.setText(user.getNickName());
loading_dialog.dismiss();
}
});
如上 DefaultTransformer 中将Response装换成T
上传代码
String uploadUrl = "http://api.vd.cn/info/getbonusnotice/";
String file = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"test.jpg";
upload_http.setEnabled(false);
Map<String, Object> map =new HashMap<String, Object>();
map.put("file",new File(file));
map.put("name","test");
RetrofitClient
.createUploadService(ApiService.class, new UploadListener() {
@Override
public void onRequestProgress(long bytesWritten, long contentLength, int progress) {
upload_http.setText( progress+"%");
if (bytesWritten==contentLength){
upload_http.setText( "上传完毕");
Log.e("tag","上传完毕");
}
}
})
.uploadFile(uploadUrl,RetrofitClient.getUploadParam(map))
.compose(Transformer.<ResponseBody>switchSchedulers())
.doFinally(new Action() {
@Override
public void run() throws Exception {
upload_http.setEnabled(true);
}
})
.subscribe(new BaseObserver<String>() {
@Override
public void onSuccess(String s) {
upload_http.setText("上传完毕");
Log.e("tag", "responseBody" +s);
}
@Override
public void onError(ApiException exception) {
upload_http.setText("上传失败");
Log.e("tag", "responseBody" + exception.response);
}
});
下载代码
String url = "https://t.alipayobjects.com/L1/71/100/and/alipay_wap_main.apk";
final String fileName = "alipay.apk";
String fileDir = getExternalFilesDir(null) + File.separator;
RetrofitClient
.createDownloadService(ApiService.class)
.downloadFile(url)
.subscribe(new DownloadObserver(fileDir,fileName) {
@Override
public void onError(int code, String s) {
}
@Override
public void onProgress(long bytesRead, long contentLength, int progress) {
download_http.setText("下载中:" + progress + "%");
}
@Override
public void onSuccess(String filePath) {
download_http.setEnabled(true);
download_http.setText("文件下载");
responseTv.setText("下载文件路径:"+filePath);
}
});
download_http.setEnabled(false);
具体见代码
作者 [@wanghaitao]
2018 年 03月 01日