日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Retrofit+RxJava+OkHttp项目中的使用

發布時間:2024/10/12 java 82 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Retrofit+RxJava+OkHttp项目中的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

近來比較火的網絡框架,自己項目中已經使用了,

1.Retrofit簡單的一句話就是通過通過代理方式和注解轉換成一個serviceMethod然后調用callFactory執行的okhttp3.Callt得到返回的數據serviceMethod.callAdapter.adapt(okHttpCall)來產生method所定義的返回值。

簡單使用

注解請求方式用途
@PathGET用于替換Url路徑中的變量字符
@QueryGET用于拼接在Url路徑后的查詢參數,但相對于直接在Url后拼接,@Query則是添加一個變量
@QueryMapGET效果等同于多個@Query 參數為Map類型
@FormUrlEncoded/@FieldPOST@FormUrlEncoded修飾表單域,每個表單域子件key-value采用@Field修飾
@BodyPOST可以指定一個對象作為HTTP請求體@Body
@FormUrlEncoded/@FieldPUT@FormUrlEncoded修飾表單域,每個表單域子件key-value采用@Field修飾
@HTTP/@BodyDELETE@HTTP修飾表單域,以指定一個對象作為HTTP請求體@Body,此時表單域一定要寫上hasBody = true
@Multipart/@Part或者@PartMapPOST文件上傳使用,@Multipart修飾表單域,參數@Part修飾或者參數使用@PartMap

上面就是常用的注解

第一步


第二步
創建retrofit 對像



?private static Retrofit getRetrofit() {
? ? ? ? if (retrofit == null) {
? ? ? ? ? ? synchronized (Http.class) {
? ? ? ? ? ? ? ? if (retrofit == null) {
? ? ? ? ? ? ? ? ? ? //添加一個log攔截器,打印所有的log
? ? ? ? ? ? ? ? ? ? HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
? ? ? ? ? ? ? ? ? ? //可以設置請求過濾的水平,body,basic,headers
? ? ? ? ? ? ? ? ? ? httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
? ? ? ? ? ? ? ? ? ? //設置 請求的緩存的大小跟位置
? ? ? ? ? ? ? ? ? ? File cacheFile = new File(MyApplication.getInstance().getmContext().getCacheDir(), "cache");
? ? ? ? ? ? ? ? ? ? Cache cache = new Cache(cacheFile, 1024 * 1024 * 50); //50Mb 緩存的大小
? ? ? ? ? ? ? ? ? ? client = new OkHttpClient
? ? ? ? ? ? ? ? ? ? ? ? ? ? .Builder()
? ? ? ? ? ? ? ? ? ? ? ? ? ? .addInterceptor(addQueryParameterInterceptor())? //參數添加
? ? ? ? ? ? ? ? ? ? ? ? ? ? .addInterceptor(addHeaderInterceptor()) // token過濾
? ? ? ? ? ? ? ? ? ? ? ? ? ? .addInterceptor(httpLoggingInterceptor) //日志,所有的請求響應度看到
? ? ? ? ? ? ? ? ? ? ? ? ? ? .addInterceptor(addCacheInterceptor())//緩存信息
? ? ? ? ? ? ? ? ? ? ? ? ? ? .cache(cache)? //添加緩存
? ? ? ? ? ? ? ? ? ? ? ? ? ? .connectTimeout(12, TimeUnit.SECONDS)
? ? ? ? ? ? ? ? ? ? ? ? ? ? .readTimeout(12, TimeUnit.SECONDS)
? ? ? ? ? ? ? ? ? ? ? ? ? ? .writeTimeout(12, TimeUnit.SECONDS)
? ? ? ? ? ? ? ? ? ? ? ? ? ? .build();


? ? ? ? ? ? ? ? ? ? // 獲取retrofit的實例
? ? ? ? ? ? ? ? ? ? retrofit = new Retrofit
? ? ? ? ? ? ? ? ? ? ? ? ? ? .Builder()
? ? ? ? ? ? ? ? ? ? ? ? ? ? .baseUrl(UrlHelper.BASE_URL)? //自己配置
? ? ? ? ? ? ? ? ? ? ? ? ? ? .client(client)
? ? ? ? ? ? ? ? ? ? ? ? ? ? .addConverterFactory(ResponseConverterFactory.create())
? ? ? ? ? ? ? ? ? ? ? ? ? ? .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
? ? ? ? ? ? ? ? ? ? ? ? ? ? .build();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return retrofit;
? ? }

?在這一步的時候你可以常用信息放在里面作為頭部信息,在這里用到了單例模式.

第三步

?創建api 接口


加上@GET 標簽,標簽后面是這個接口的 尾址sign/login,完整的地址應該是 baseUrl+尾址 ,參數 使用@Query標簽,如果參數多的話可以用@QueryMap標 簽,接收一個Map。

常見的post請求和GET請求方式,如果要傳的表單形式記得要加上?@Multipart 同時注解里面@Part List<MultipartBody.Part> partList 這種方式就是常見的圖片和文字上傳。

從第二步可以看出創建http請求類,并在里面初始化并配置Retrofit和OkHttp: 同時采用建造者模式添加攔截比如addQueryParameterInterceptor(),addHeaderInterceptor(),

addQueryParameterInterceptor()類中:


這里設置基本信息,當hain.proceed(request)時表示進行okhttp下一步操作

addHeaderInterceptor()


設置頭的基本信息。

第四步進行數據返回,在返回時做些處理重新ResponseConverterFactory extends Converter.Factory 為什么處理呢?因為后臺返回來的數據有時返回有問題,


然后?通過GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> 這樣子的話我直接可以得到返回的值。

public class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
? ? private final Type type;


? ? public GsonResponseBodyConverter(Gson gson, Type type) {
? ? ? ? this.type = type;
? ? }


? ? /**
? ? ?* @param value
? ? ?* @return
? ? ?* @throws IOException
? ? ?*/
? ? @Override
? ? public T convert(ResponseBody value) {
? ? ? ? int? errorCode=0;
? ? ? ? String? errorMesage="";
? ? ? ? try {
? ? ? ? ? ? String result = value.string();
? ? ? ? ? ? JSONObject jsonObject = new JSONObject(result);
? ? ? ? ? ? if (ConstantUrl.IS_DENCRYPT) {
? ? ? ? ? ? ? ? String datas = jsonObject.optString("sign");
? ? ? ? ? ? ? ? if(jsonObject.optInt("error_code") != ConstantUrl.error_code1){
? ? ? ? ? ? ? ? ? ? jsonObject = new JSONObject(AESUtils.decrypt(datas));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if ((jsonObject.optInt("error_code") ==ConstantUrl.error_code3)||(jsonObject.optInt("error_code") == ConstantUrl.error_code2)) {
? ? ? ? ? ? ? ? String data = jsonObject.optString("data");
? ? ? ? ? ? ? ? //常規數據請求接口數據
? ? ? ? ? ? ? ? if (!TextUtils.isEmpty(data) && !data.equals("null")) {
? ? ? ? ? ? ? ? ? ? if(type != String.class){
? ? ? ? ? ? ? ? ? ? ? ? return new Gson().fromJson(data,type);
? ? ? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ? ? ? return (T)data;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? //data里面沒有數據
? ? ? ? ? ? ? ? ? ? errorCode=jsonObject.optInt("error_code");
? ? ? ? ? ? ? ? ? ? errorMesage=jsonObject.optString("error_message");
? ? ? ? ? ? ? ? ? ? throw new ResultException(jsonObject.optInt("error_code"), jsonObject.optString("error_message"));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? //ErrResponse 將msg解析為異常消息文本
? ? ? ? ? ? ? ? errorCode=jsonObject.optInt("error_code");
? ? ? ? ? ? ? ? errorMesage=jsonObject.optString("error_message");
? ? ? ? ? ? ? ? throw new ResultException(jsonObject.optInt("error_code"), jsonObject.optString("error_message"));
? ? ? ? ? ? }
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? throw new ResultException(0, UiUtils.getString(R.string.httpSubmitContextNull));
? ? ? ? } catch (JSONException e) {
? ? ? ? ? ? throw new ResultException(0, UiUtils.getString(R.string.JsonSyntaxException));
? ? ? ? } catch (RuntimeException e) {
? ? ? ? ? ? ErrResponse errResponse = new ErrResponse();
? ? ? ? ? ? errResponse.setMsg(UiUtils.getString(R.string.systemExpire));
? ? ? ? ? ? throw new ResultException(errorCode, errorMesage);
? ? ? ? }
? ? }

通過gson 方式把數據轉換成自己想要的,這個時候自己定義Exception處理類,


數據返回第二步 通過Rxjava把數據帶回,Exception處理分為2部分,本身Exception和服務器返回的Exception,

分開處理,

public abstract class AbsAPICallback<T> extends Subscriber<T> {
? ? protected? Context mContext;
? ? private ProgressBarDialog dialog = null;
? ? public? AbsAPICallback(Context context,boolean isLoadProgress) {
? ? ? ? this.mContext = context;
? ? ? ? if(isLoadProgress && dialog == null){
? ? ? ? ? ? dialog = new ProgressBarDialog(context);
? ? ? ? }
? ? ? ? if(isLoadProgress && dialog!=null){
? ? ? ? ? ? dialog.showProgress();
? ? ? ? }
? ? }


? ? @Override
? ? public void onError(Throwable e) {
? ? ? ? if(dialog!=null&&dialog.isShowing()){
? ? ? ? ? ? dialog.closeProgress();
? ? ? ? }
? ? ? ? Log.e("e","httpException = " +e);
? ? ? ? Throwable throwable = e;
? ? ? ? //獲取最根源的異常
? ? ? ? while (throwable.getCause() != null) {
? ? ? ? ? ? e = throwable;
? ? ? ? ? ? throwable = throwable.getCause();
? ? ? ? }
? ? ? ? if (e instanceof HttpException) {//HTTP錯誤
? ? ? ? ? ? HttpException httpException = (HttpException) e;
? ? ? ? ? ? switch (httpException.code()) {
? ? ? ? ? ? ? ? case IntegerUtil.ABS_UNAUTHORIZED:
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case IntegerUtil.ABS_FORBIDDEN:
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case IntegerUtil.ABS_NOT_FOUND:
? ? ? ? ? ? ? ? ? ? ToastUtil.showShort(UiUtils.getString(R.string.noNetWork));
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case IntegerUtil.ABS_REQUEST_TIMEOUT:
? ? ? ? ? ? ? ? ? ? ToastUtil.showShort(UiUtils.getString(R.string.timeout));
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case IntegerUtil.ABS_GATEWAY_TIMEOUT:
? ? ? ? ? ? ? ? ? ? ToastUtil.showShort(UiUtils.getString(R.string.timeout));
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case IntegerUtil.ABS_INTERNAL_SERVER_ERROR:
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case IntegerUtil.ABS_BAD_GATEWAY:
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case IntegerUtil.ABS_SERVICE_UNAVAILABLE:
? ? ? ? ? ? ? ? ? ? ToastUtil.showShort(UiUtils.getString(R.string.unavailable));
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? LogUtils.d(UiUtils.getString(R.string.InternalServerError));
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? } else if (e instanceof SocketTimeoutException) {
? ? ? ? ? ? String message = UiUtils.getString(R.string.timeout);
? ? ? ? ? ? ToastUtil.showShort(message);
? ? ? ? ? ? ResultException resultException = new ResultException(0,message);
? ? ? ? ? ? onResultError(resultException);
? ? ? ? } else if (e instanceof ResultException) {//服務器返回的錯誤
? ? ? ? ? ? ResultException resultException = (ResultException) e;
? ? ? ? ? ? switchError(resultException);
? ? ? ? } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) {
? ? ? ? ? ? LogUtils.d(UiUtils.getString(R.string.JsonSyntaxException));
? ? ? ? } else if(e instanceof ConnectException){
? ? ? ? ? ? String message = UiUtils.getString(R.string.noNetWork);
? ? ? ? ? ? ToastUtil.showShort(message);
? ? ? ? ? ? ResultException resultException = new ResultException(0,message);
? ? ? ? ? ? onResultError(resultException);
? ? ? ? }
? ? }
? ? /**
? ? ?* 服務器返回的錯誤
? ? ?*/
? ? protected abstract void onResultError(ResultException ex);


? ? protected abstract void onDone(T t);


? ? @Override
? ? public void onCompleted() {


? ? }
? ? private ConfirmDialog comfirmDialog;
? ? private void switchError(ResultException resultException){
? ? ? ? switch (resultException.getErrCode()){
? ? ? ? ? ? case IntegerUtil.ABS_TOKEN_FAIL://您的賬號登錄異常,請重新登錄!
? ? ? ? ? ? ? ? ToastUtil.showShort(UiUtils.getString(R.string.tokenVerifyFail));
? ? ? ? ? ??
? ? ? ? ? ? ? ? break;


? ? ? ? ? ? case IntegerUtil.ABS_TOKEN_EXPIRE://您的賬號已過期,為確保信息安全,請重新登錄!
? ? ? ? ? ? ? ? FragmentManager mamage = ((AppCompatActivity) mContext).getSupportFragmentManager();
? ? ? ? ? ? ? ? if(comfirmDialog==null)
? ? ? ? ? ? ? ? ? ? comfirmDialog = ConfirmDialog.newInstance("", UiUtils.getString( R.string.tokenVerifyExpire) , "稍后再說", "立即登錄");
? ? ? ? ? ? ? ? if(comfirmDialog.isVisible())
? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? comfirmDialog.setMargin(60)
? ? ? ? ? ? ? ? ? ? ? ? .setWidth(SystemInfoUtil.getScreenWidth()*2/3)
? ? ? ? ? ? ? ? ? ? ? ? .setOutCancel(false)
? ? ? ? ? ? ? ? ? ? ? ? .show(mamage);
? ? ? ? ? ? ? ? comfirmDialog.setConfirmDialogListener(new ConfirmDialog.ConfirmDialogListener(){
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public void dialogStatus(int id) {
? ? ? ? ? ? ? ? ? ? ? ? switch (id){
? ? ? ? ? ? ? ? ? ? ? ? ? ? case R.id.cancel:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //取消 到首頁
? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? ? ? ? ? ? case R.id.ok:
? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? break;


? ? ? ? ? ? case IntegerUtil.ABS_TOKEN_POST_NULL://請求token不能為空? ? ? ? ? ??
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? onResultError(resultException);
? ? ? ? ? ? ? ? break;


? ? ? ? }
? ? }


? ? @Override
? ? public void onNext(T t) {
? ? ? ? onDone(t);
? ? ? ? if(dialog!=null&&dialog.isShowing()){
? ? ? ? ? ? dialog.closeProgress();
? ? ? ? }
? ? }

最后一步,調用實現

? ?HttpService httpService = Http.getHttpService();
? ? ? ? Map<String, Object> map = new HashMap<String, Object>();
? ? ? ? map.put("courseId", courseId);
? ? ? ? httpService.payDirectInfo(RequestBodyUtils.setRequestBody(map))
? ? ? ? ? ? ? ? .subscribeOn(Schedulers.io())
? ? ? ? ? ? ? ? .observeOn(Schedulers.io())
? ? ? ? ? ? ? ? .observeOn(AndroidSchedulers.mainThread())
? ? ? ? ? ? ? ? .subscribe(new AbsAPICallback<PayDirectInfo>(mContext, true) {
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? protected void onDone(PayDirectInfo strTeacher) {

? ? ? ? ? ? ? ? ? ?


? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public void onResultError(ResultException ex) {
? ? ? ? ? ? ? ? ? ? ? ? ToastUtil.showToast(ex.getMessage());
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });


? ? }


有問題,請隨時留言或加本人QQ:874993467

總結

以上是生活随笔為你收集整理的Retrofit+RxJava+OkHttp项目中的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。