Retrofit详解(下)

xiaoxiao2021-02-28  78

Retrofit基础讲解

https://blog.csdn.net/weixin_37730482/article/details/73606913

 

本章节讲述RxJava+RxAndroid+Retrofit实现网络请求

 

 

 

一.项目配置

//RxJava依赖 异步 子线程请求网络数据 implementation 'io.reactivex:rxjava:1.3.2' //RxAndroid依赖 AndroidUI更新UI implementation 'io.reactivex:rxandroid:1.2.1' //Retrofit依赖 网络框架 implementation 'com.squareup.retrofit2:retrofit:2.7.0' //Gson依赖 和retrofit对应的gson解析类库,配置了就拥有了json解析的功能 implementation 'com.squareup.retrofit2:converter-gson:2.7.0'

 

 

 

 

二.项目结构

 

 

 

 

 

 

三.代码实现

 

<1> Retrofit管理类

package com.example.myapplication.retrofit.manager; import android.text.TextUtils; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitManager { private static final long nettimeout = 20;//超时时间20秒 private Retrofit mRetrofit; private static RetrofitManager retrofitManager = null; /** * 获取此单例类对象的方法 */ public static RetrofitManager getInstance(String baseUrl) { if (null == retrofitManager) {//单例对象为空 synchronized (RetrofitManager.class) { retrofitManager = new RetrofitManager(baseUrl); } } return retrofitManager; } /** * 构造方法 */ private RetrofitManager(String baseUrl) { if (TextUtils.isEmpty(baseUrl) || !(baseUrl.endsWith("/"))) { return; } //配置okHttp的参数 OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectTimeout(nettimeout, TimeUnit.SECONDS) .build(); //获取Retrofit对象 mRetrofit = new Retrofit.Builder() .baseUrl(baseUrl)//设置BaseUrl 必须以'/'结尾 .client(okHttpClient)//设置请求的client .addConverterFactory(GsonConverterFactory.create())//设置转换器 .build(); } public Retrofit getRetrofit() { return mRetrofit; } }

 

 

<2> 翻译模块

 

Model层

package com.example.myapplication.retrofit.model; import android.text.TextUtils; import android.util.Log; import com.example.myapplication.retrofit.api.FanYiApiService; import com.example.myapplication.retrofit.bean.FanYiBean; import com.example.myapplication.retrofit.manager.RetrofitManager; import com.example.myapplication.retrofit.presenter.FanYiPresenter; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import rx.Observable; import rx.Observer; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; public class FanYiModel { private FanYiPresenter presenter; public FanYiModel(FanYiPresenter presenter) { this.presenter = presenter; } /** * 请求翻译数据 */ public void getFanYiData() { Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { //create操作符创建被观察者 call方法中执行网络请求操作 Retrofit retrofit = RetrofitManager.getInstance(FanYiApiService.fanyiBaseUrl).getRetrofit(); if (null != retrofit) { FanYiApiService fanYiApiService = retrofit.create(FanYiApiService.class); if (null != fanYiApiService) { Call<ResponseBody> call = fanYiApiService.getFanYiData(); if (null != call) { call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (null != response && response.isSuccessful()) { String result = ""; try { result = response.body().string(); } catch (IOException e) { e.printStackTrace(); } subscriber.onNext(result); subscriber.onCompleted(); } else { subscriber.onError(null); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { subscriber.onError(t); } }); } } } Log.d("FanYiModel", "被观察者 call方法 线程----:" + Thread.currentThread().getName()); } }).subscribeOn(Schedulers.io())//被观察者 请求网络数据 IO线程执行 .observeOn(AndroidSchedulers.mainThread())//观察者 回调 UI线程执行 .subscribe(new Observer<String>() { @Override public void onCompleted() { Log.d("FanYiModel", "观察者 onCompleted方法 线程----:" + Thread.currentThread().getName()); } @Override public void onError(Throwable e) { withJsonData("", e); Log.d("FanYiModel", "观察者 onError方法 线程----:" + Thread.currentThread().getName()); } @Override public void onNext(String string) { withJsonData(string, null); Log.d("FanYiModel", "观察者 onNext方法 线程----:" + Thread.currentThread().getName()); } }); } /** * Json解析数据 */ private void withJsonData(String json, Throwable t) { Log.d("FanYiModel", "翻译模块Json解析数据 json----:" + json); Log.d("FanYiModel", "翻译模块Json解析数据 t----:" + t); FanYiBean bean = new FanYiBean(); if (!TextUtils.isEmpty(json)) { String translation = ""; String basic = ""; try { JSONObject jsonObject = new JSONObject(json); translation = jsonObject.optString("translation"); basic = jsonObject.optString("basic"); } catch (JSONException ex) { ex.printStackTrace(); } bean.setTranslation(translation); bean.setBasic(basic); } else { if (null != t) { bean.setT(t); } } //最终回调Presenter if (null != presenter) { presenter.updateUI(bean); } } } D/FanYiModel: 被观察者 call方法 线程----:RxIoScheduler-3 D/FanYiModel: 观察者 onNext方法 线程----:main D/FanYiModel: 观察者 onCompleted方法 线程----:main

 

View层

package com.example.myapplication.retrofit.view; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.myapplication.R; import com.example.myapplication.retrofit.bean.FanYiBean; import com.example.myapplication.retrofit.callback.FanYiCallBack; import com.example.myapplication.retrofit.presenter.FanYiPresenter; public class RetrofitTest1Activity extends AppCompatActivity implements FanYiCallBack { private TextView textView; private FanYiPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_retrofittest1); findView(); } /** * 初始化各种View */ private void findView() { textView = findViewById(R.id.activity_rerofittes1_textview); presenter = new FanYiPresenter(this); getFanYiData(); } /** * 请求数据 */ private void getFanYiData() { if (null != presenter) { presenter.getFanYiData(); } } /** * 接口回调 */ @Override public void updateResult(FanYiBean bean) { if (null != bean) { String translation = bean.getTranslation(); String basic = bean.getBasic(); String result = "Translation:" + translation + " Basic:" + basic; textView.setText(result); } } } <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/activity_rerofittes1_textview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:background="@color/colorPrimary" android:gravity="center" android:textColor="#FFFFFF" android:textSize="16dp" /> </LinearLayout>

 

Presenter层

package com.example.myapplication.retrofit.presenter; import com.example.myapplication.retrofit.bean.FanYiBean; import com.example.myapplication.retrofit.callback.FanYiCallBack; import com.example.myapplication.retrofit.model.FanYiModel; public class FanYiPresenter { private FanYiCallBack callBack; private FanYiModel model; public FanYiPresenter(FanYiCallBack callBack) { this.callBack = callBack; model = new FanYiModel(this); } /** * 请求翻译数据 */ public void getFanYiData() { if (null != model) { model.getFanYiData(); } } /** * 最终回调UI */ public void updateUI(FanYiBean bean) { if (null == callBack || null == bean) { return; } callBack.updateResult(bean); } }

 

CallBack

package com.example.myapplication.retrofit.callback; import com.example.myapplication.retrofit.bean.FanYiBean; public interface FanYiCallBack { void updateResult(FanYiBean bean); }

 

API

package com.example.myapplication.retrofit.api; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.GET; /** * 翻译API */ public interface FanYiApiService { /** * 翻译模块BaseUrl 须以"/"结尾 */ String fanyiBaseUrl = "http://fanyi.youdao.com/"; /** * 翻译模块 get请求 */ @GET("openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue") Call<ResponseBody> getFanYiData(); }

 

Bean

package com.example.myapplication.retrofit.bean; public class FanYiBean { private String translation; private String basic; private Throwable t; public String getTranslation() { return translation; } public void setTranslation(String translation) { this.translation = translation; } public String getBasic() { return basic; } public void setBasic(String basic) { this.basic = basic; } public Throwable getT() { return t; } public void setT(Throwable t) { this.t = t; } }

 

 

<3> 登录模块

 

Model层

package com.example.myapplication.retrofit.model; import android.text.TextUtils; import android.util.Log; import com.example.myapplication.retrofit.api.LoginApiService; import com.example.myapplication.retrofit.bean.LoginBean; import com.example.myapplication.retrofit.manager.RetrofitManager; import com.example.myapplication.retrofit.presenter.LoginPresenter; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import rx.Observable; import rx.Observer; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; public class LoginModel { private LoginPresenter presenter; public LoginModel(LoginPresenter presenter) { this.presenter = presenter; } /** * 登录 */ public void loginService(String param1, String param2, String param3, String param4, String param5, String param6) { Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { //create操作符创建被观察者 call方法中执行网络请求操作 Retrofit retrofit = RetrofitManager.getInstance(LoginApiService.fanyiBaseUrl).getRetrofit(); if (null != retrofit) { LoginApiService loginApiService = retrofit.create(LoginApiService.class); if (null != loginApiService) { Call<ResponseBody> call = loginApiService.login(param1, param2, param3, param4, param5, param6); if (null != call) { call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (null != response && response.isSuccessful()) { String result = ""; try { result = response.body().string(); } catch (IOException e) { e.printStackTrace(); } subscriber.onNext(result); subscriber.onCompleted(); } else { subscriber.onError(null); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { subscriber.onError(t); } }); } } } Log.d("LoginModel", "被观察者 call方法 线程----:" + Thread.currentThread().getName()); } }).subscribeOn(Schedulers.io())//被观察者 请求网络数据 IO线程执行 .observeOn(AndroidSchedulers.mainThread())//观察者 回调 UI线程执行 .subscribe(new Observer<String>() { @Override public void onCompleted() { Log.d("LoginModel", "观察者 onCompleted方法 线程----:" + Thread.currentThread().getName()); } @Override public void onError(Throwable e) { withJsonData("", e); Log.d("LoginModel", "观察者 onError方法 线程----:" + Thread.currentThread().getName()); } @Override public void onNext(String string) { withJsonData(string, null); Log.d("LoginModel", "观察者 onNext方法 线程----:" + Thread.currentThread().getName()); } }); } /** * Json解析数据 */ private void withJsonData(String json, Throwable t) { Log.d("LoginModel", "登录模块Json解析数据 json----:" + json); Log.d("LoginModel", "登录模块Json解析数据 t----:" + t); LoginBean bean = new LoginBean(); if (!TextUtils.isEmpty(json)) { String translation = ""; String basic = ""; try { JSONObject jsonObject = new JSONObject(json); translation = jsonObject.optString("translation"); basic = jsonObject.optString("basic"); } catch (JSONException ex) { ex.printStackTrace(); } bean.setTranslation(translation); bean.setBasic(basic); } else { if (null != t) { bean.setT(t); } } //最终回调Presenter if (null != presenter) { presenter.updateUI(bean); } } } D/LoginModel: 被观察者 call方法 线程----:RxIoScheduler-3 D/LoginModel: 观察者 onNext方法 线程----:main D/LoginModel: 观察者 onCompleted方法 线程----:main

 

View层

package com.example.myapplication.retrofit.view; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; import com.example.myapplication.R; import com.example.myapplication.retrofit.bean.LoginBean; import com.example.myapplication.retrofit.callback.LoginCallBack; import com.example.myapplication.retrofit.presenter.LoginPresenter; public class RetrofitTest2Activity extends AppCompatActivity implements LoginCallBack { private TextView textView; private LoginPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_retrofittest2); findView(); } /** * 初始化各种View */ private void findView() { textView = findViewById(R.id.activity_rerofittes2_textview); presenter = new LoginPresenter(this); loginService("imoocdict123456", "324273592", "data", "json", "1.1", "red"); } /** * 登录 */ public void loginService(String param1, String param2, String param3, String param4, String param5, String param6) { if (null != presenter) { presenter.loginService(param1, param2, param3, param4, param5, param6); } } /** * 接口回调 */ @Override public void updateResult(LoginBean bean) { if (null != bean) { String translation = bean.getTranslation(); String basic = bean.getBasic(); String result = "Translation:" + translation + " Basic:" + basic; textView.setText(result); } } } <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/activity_rerofittes2_textview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:background="@color/colorAccent" android:gravity="center" android:textColor="#FFFFFF" android:textSize="16dp" /> </LinearLayout>

 

Presenter层

package com.example.myapplication.retrofit.presenter; import com.example.myapplication.retrofit.bean.LoginBean; import com.example.myapplication.retrofit.callback.LoginCallBack; import com.example.myapplication.retrofit.model.LoginModel; public class LoginPresenter { private LoginModel model; private LoginCallBack callBack; public LoginPresenter(LoginCallBack callBack) { model = new LoginModel(this); this.callBack = callBack; } /** * 登录 */ public void loginService(String param1, String param2, String param3, String param4, String param5, String param6) { if (null != model) { model.loginService(param1, param2, param3, param4, param5, param6); } } /** * 最终回调UI */ public void updateUI(LoginBean bean) { if (null == callBack || null == bean) { return; } callBack.updateResult(bean); } }

 

CallBack

package com.example.myapplication.retrofit.callback; import com.example.myapplication.retrofit.bean.LoginBean; public interface LoginCallBack { void updateResult(LoginBean bean); }

 

API

package com.example.myapplication.retrofit.api; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; /** * 登录API */ public interface LoginApiService { /** * 登录模块BaseUrl 须以"/"结尾 */ String fanyiBaseUrl = "http://fanyi.youdao.com/"; /** * 登录模块 post请求 */ @FormUrlEncoded @POST("openapi.do") Call<ResponseBody> login(@Field("keyfrom") String param1, @Field("key") String params2, @Field("type") String param3, @Field("doctype") String param4, @Field("version") String param5, @Field("q") String param6); }

 

Bean

package com.example.myapplication.retrofit.bean; public class LoginBean { private String translation; private String basic; private Throwable t; public String getTranslation() { return translation; } public void setTranslation(String translation) { this.translation = translation; } public String getBasic() { return basic; } public void setBasic(String basic) { this.basic = basic; } public Throwable getT() { return t; } public void setT(Throwable t) { this.t = t; } }

 

 

 

 

四.说明

 

<1> RxJava&RxAndroid结合Retrofit使用时,对于线程的操作。其实主要是

if (null != mSubscriber && null != observable) { observable.subscribeOn(Schedulers.newThread()) //指定被观察者 生产事件的线程 .observeOn(AndroidSchedulers.mainThread()) //指定观察者 接收 & 响应事件的线程 .subscribe(mSubscriber); //最后再通过订阅(subscribe)连接观察者和被观察者 }

即:利用RxJava的线程调度类Schedulers+observable.subscribeOn 规定被观察者在IO线程 请求网络数据。

       利用RxAndroid的线程调度类AndroidSchedulers+observeOn 规定观察者在Android UI线程 更新UI。

 

具体详解

https://blog.csdn.net/weixin_37730482/article/details/72961379

 

 

<2> 此demo只为举例,所以翻译模块和登录模块接口类似。

 

 

转载请注明原文地址: https://www.6miu.com/read-37136.html

最新回复(0)