通用Bean

  1. data class WxData(
  2. var `data`: List<Data>,
  3. var errorCode: Int,
  4. var errorMsg: String
  5. )
  6. data class Data(
  7. var children: List<Any>,
  8. var courseId: Int,
  9. var id: Int,
  10. var name: String,
  11. var order: Int,
  12. var parentChapterId: Int,
  13. var userControlSetTop: Boolean,
  14. var visible: Int
  15. )

Retrofit + Gson

  • 导入最新版

    1. //retrofit
    2. api 'com.squareup.retrofit2:retrofit:2.9.0'
    3. //retrofit - gson
    4. api 'com.squareup.retrofit2:converter-gson:2.9.0'
  • Api ``` interface GsonApi {

    companion object{

    1. val BASE_URL = "https://www.wanandroid.com/"
    2. fun create(): GsonApi {
    3. return Retrofit.Builder()
    4. .baseUrl(BASE_URL)
    5. .addConverterFactory(GsonConverterFactory.create())
    6. .build()
    7. .create(GsonApi::class.java)
    8. }

    }

    @GET(“wxarticle/chapters/json”) fun getWxData(): Call

}

  1. - 使用

private fun testGson() { GsonApi.create().getWxData().enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { //获取结果 val body = response.body() Log.e(TAG, “onResponse: $body”, ) }

  1. override fun onFailure(call: Call<WxData>, t: Throwable) {
  2. Log.e(TAG, "onFailure: $t")
  3. }
  4. })

}

  1. <a name="63eedece"></a>
  2. ### Retrofit + Gson + Rxjava2 + rxlife
  3. [RxLife地址](https://github.com/liujingxing/rxlife)<br />导包:

//retrofit api ‘com.squareup.retrofit2:retrofit:2.9.0’ //retrofit - gson api ‘com.squareup.retrofit2:converter-gson:2.9.0’ //rxjava 相关 api ‘com.squareup.retrofit2:adapter-rxjava2:2.9.0’ //rxjava2 api ‘io.reactivex.rxjava2:rxandroid:2.1.1’ api “io.reactivex.rxjava2:rxjava:2.2.6” //rxlife api ‘com.rxjava.rxlife:rxlife:1.0.8’ //cookie implementation ‘com.github.franmontiel:PersistentCookieJar:v1.0.1’ implementation ‘com.squareup.okhttp3:logging-interceptor:3.8.1’

  1. - BaseBean2
  2. ```kotlin
  3. public class BaseBean2<T> {
  4. /**
  5. * result : 1
  6. * message : 请求参数为空或不合法!
  7. */
  8. private int result;// 0成功,其他失败
  9. private int errorCode;
  10. private String message;
  11. private T data;
  12. public boolean isSuccess() {
  13. return result == 0;
  14. }
  15. public T getData() {
  16. return data;
  17. }
  18. public void setData(T data) {
  19. this.data = data;
  20. }
  21. public int getResult() {
  22. return result;
  23. }
  24. public void setResult(int result) {
  25. this.result = result;
  26. }
  27. public String getMessage() {
  28. return message;
  29. }
  30. public void setMessage(String message) {
  31. this.message = message;
  32. }
  33. public int getErrorCode() {
  34. return errorCode;
  35. }
  36. public void setErrorCode(int errorCode) {
  37. this.errorCode = errorCode;
  38. }
  39. }
  • RetrofitHelp ``` public class RetrofitHelp {

    private Retrofit retrofit; private String mBaseUrl = HttpConfig.sBaseUrl;

    private RetrofitHelp() {

    1. initRetrofit();

    }

    private void initRetrofit() {

    1. // 指定缓存路径,缓存大小 50Mb
    2. Cache cache = new Cache(new File(HttpConfig.sContext.getCacheDir(), "HttpCache"),
    3. 1024 * 1024 * 50);
    4. // Cookie 持久化
    5. ClearableCookieJar cookieJar =
    6. new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(HttpConfig.sContext));
    7. OkHttpClient.Builder builder = new OkHttpClient.Builder()
    8. .cookieJar(cookieJar)
    9. //.sslSocketFactory(SSLHelper.getSSLCertifcation(context))
    10. .cache(cache)

    // .addInterceptor(cacheControlInterceptor)//有网策略

    1. //.addNetworkInterceptor(cacheControlInterceptor)//无网策略
    2. .connectTimeout(60, TimeUnit.SECONDS)
    3. .readTimeout(30, TimeUnit.SECONDS)
    4. .writeTimeout(30, TimeUnit.SECONDS)
    5. // .addNetworkInterceptor(new StethoInterceptor())
    6. .retryOnConnectionFailure(true);
    7. if (BuildConfig.DEBUG) {
    8. SdkManager.initInterceptor(builder);
    9. }
    10. Gson gson = new GsonBuilder()
    11. .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
    12. .serializeNulls()
    13. .registerTypeAdapter(String.class, new StringConverter())//对为null的字段进行转换
    14. .create();
    15. retrofit = new Retrofit.Builder()
    16. .baseUrl(mBaseUrl)
    17. .client(builder.build())
    18. .addConverterFactory(GsonConverterFactory.create(gson))

    // .addConverterFactory(GsonDConverterFactory.create(gson))

    1. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    2. .build();

    }

    /**

    • 实现了序列化接口 对为null的字段进行转换 */ public static class StringConverter implements JsonSerializer, JsonDeserializer { //字符串为null 转换成””,否则为字符串类型 @Override public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

      1. return json.getAsJsonPrimitive().getAsString();

      }

      @Override public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {

      1. return src == null || src.equals("null") ? new JsonPrimitive("") : new JsonPrimitive(src);

      } }

      private static class SingletonInstance { private static final RetrofitHelp INSTANCE = new RetrofitHelp(); }

      public static RetrofitHelp getInstance() { return SingletonInstance.INSTANCE; }

  1. public <T> T create(Class<T> service) {
  2. if (retrofit == null){
  3. mBaseUrl = HttpConfig.sBaseUrl;
  4. initRetrofit();
  5. }
  6. return retrofit.create(service);
  7. }

// public T create(Class service, String url) { // initRetrofit(); // mBaseUrl = url; // return retrofit.create(service); // }

}

  1. - RxSubUtils

public abstract class RxSubUtils extends DisposableSubscriber { private static final String TAG = “RxSubUtils”; public static final int RESULT_ERROR = 99999;//返回error //private CompositeDisposable compositeDisposable; /**

  1. * 弱引用
  2. */
  3. private WeakReference<Context> mContext;
  4. //private Context mContext;
  5. private String msg;//提示内容
  6. private boolean isShow;

// private LoadingDialog loadingDialog;

// public RxSubUtils(CompositeDisposable mCompositeSubscription) { // this.compositeDisposable = mCompositeSubscription; // }

  1. public RxSubUtils(){}//无参数,一般不用提示对话框
  2. public RxSubUtils(Context context, String hint) {//自定义提示对话框内容
  3. this(context, hint, true);
  4. }
  5. public RxSubUtils(Context context) {//默认对话框内容
  6. //mContext=context;
  7. //this.mContext=new WeakReference<Context>(context);
  8. this(context, "初始化...");
  9. }
  10. public RxSubUtils(Context context, boolean isShow) {
  11. this(context, "初始化...", isShow);
  12. }
  13. public RxSubUtils(Context context, String hint, boolean isShow) {
  14. this.mContext = new WeakReference<Context>(context);
  15. this.msg = hint;
  16. this.isShow = isShow;
  17. }
  18. /**
  19. * 这个一定要有 Presenter的逻辑在这里处理
  20. *
  21. * @param t
  22. */
  23. @Override
  24. public void onNext(T t) {
  25. _onNext(t);
  26. }
  27. @Override
  28. public void onError(Throwable e) {
  29. e.printStackTrace();
  30. Log.e(TAG, "onError: " + e.toString());
  31. if (isShow) {
  32. hintDialog();
  33. }
  34. //判断e内容
  35. String message = "";
  36. int result = 0;
  37. if (e instanceof ServerException){
  38. //后台返回错误相关
  39. result = ((ServerException) e).getResult();
  40. }else {
  41. //其他错误原因
  42. result = RESULT_ERROR;
  43. }
  44. message = e.getMessage();
  45. Log.e(TAG, "onError: reuslt = " + result + "msg = " + message);
  46. _onError(e,result, message);
  47. }
  48. @Override
  49. public void onComplete() {

// if (compositeDisposable != null) // compositeDisposable.clear(); // Log.e(TAG, “onComplete: “ ); //LoadingDialogManager.getLoadingDialog().hideDialog(); if (isShow) { hintDialog(); } }

  1. private void hintDialog() {
  2. Context context = mContext.get();
  3. if (context == null) {
  4. return;
  5. }

// if (loadingDialog != null) { // loadingDialog.close(); // } }

  1. @Override
  2. public void onStart() {
  3. super.onStart();
  4. /*if (mContext != null) {
  5. LoadingDialogManager.getLoadingDialog().showDialog(mContext);
  6. }*/
  7. //获取context
  8. if (isShow) {
  9. initDialog();
  10. }
  11. }
  12. private void initDialog() {
  13. Context context = mContext.get();
  14. if (context == null) {
  15. return;
  16. }

// loadingDialog = new LoadingDialog(context, false); // loadingDialog.setLoadingText(msg) // .setInterceptBack(true) // .setLoadStyle(LoadingDialog.STYLE_LINE) // .show(); }

  1. protected abstract void _onNext(T t);
  2. protected abstract void _onError(Throwable e, int result, String msg);

// /* // 错误处理,需要的话重写这个方法 // */ // protected void _onError(String err, int status) { // if (!TextUtils.isEmpty(err)) { //// ToastUtils.showShort(err); // } // }

}

  1. - RxUtils

public class RxUtils { private static FlowableTransformer ioToMainThreadSchedulerTransformer; private static FlowableTransformer newThreadToMainThreadSchedulerTransformer;

  1. static {
  2. ioToMainThreadSchedulerTransformer = createIOToMainThreadScheduler();
  3. newThreadToMainThreadSchedulerTransformer = createNewThreadToMainThreadScheduler();
  4. }
  5. private static <T> FlowableTransformer<T, T> createIOToMainThreadScheduler() {
  6. return tObservable -> tObservable.subscribeOn(Schedulers.io())
  7. .unsubscribeOn(Schedulers.computation())
  8. .observeOn(AndroidSchedulers.mainThread());
  9. }
  10. /**
  11. * 从IO线程切换到主线程
  12. *
  13. * @param <T>
  14. * @return
  15. */
  16. public static <T> FlowableTransformer<T, T> applyIOToMainThreadSchedulers() {
  17. return ioToMainThreadSchedulerTransformer;
  18. }
  19. private static <T> FlowableTransformer<T, T> createNewThreadToMainThreadScheduler() {
  20. return tObservable -> tObservable.subscribeOn(Schedulers.newThread())
  21. .unsubscribeOn(Schedulers.computation())
  22. .unsubscribeOn(Schedulers.io())
  23. .observeOn(AndroidSchedulers.mainThread());
  24. }
  25. public static <T> FlowableTransformer<T, T> applyNewThreadToMainThreadSchedulers() {
  26. return newThreadToMainThreadSchedulerTransformer;
  27. }
  28. /**
  29. * io -----> main
  30. * @param <T>
  31. * @return
  32. */
  33. public static <T> FlowableTransformer<T, T> ioToMain() {
  34. return upstream -> upstream.subscribeOn(Schedulers.io())
  35. .observeOn(AndroidSchedulers.mainThread());
  36. }
  37. /**
  38. * 简单处理一下数据
  39. *
  40. * @param <T>
  41. * @return
  42. */
  43. public static <T> FlowableTransformer<BaseBean2<T>, T> handleBaseBean() {
  44. return upstream -> upstream.flatMap(new Function<BaseBean2<T>, Publisher<T>>() {
  45. @Override
  46. public Publisher<T> apply(@io.reactivex.annotations.NonNull BaseBean2<T> tBaseBean2) throws Exception {
  47. if (tBaseBean2.isSuccess()) {
  48. return createData(tBaseBean2.getData());
  49. } else {
  50. return Flowable.error(new ServerException(tBaseBean2.getResult(), tBaseBean2.getErrorCode(), tBaseBean2.getMessage()));
  51. }
  52. }
  53. }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
  54. }
  55. /**
  56. * 创建成功的数据
  57. *
  58. * @param data
  59. * @param <T>
  60. * @return
  61. */
  62. private static <T> Flowable<T> createData(T data) {
  63. return Flowable.create(new FlowableOnSubscribe<T>() {
  64. @Override
  65. public void subscribe(@NonNull FlowableEmitter<T> flowableEmitter) throws Exception {
  66. try {
  67. flowableEmitter.onNext(data);
  68. flowableEmitter.onComplete();
  69. } catch (Exception e) {
  70. flowableEmitter.onError(e);
  71. }
  72. }
  73. }, BackpressureStrategy.BUFFER);
  74. }

}

  1. - SdkManager

public class SdkManager { // public static void initStetho(Context context) { // Stetho.initializeWithDefaults(context); // }

  1. public static OkHttpClient.Builder initInterceptor(OkHttpClient.Builder builder) {
  2. HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
  3. @Override
  4. public void log(String message) {
  5. Log.e("Okhttp", "log: " + message );
  6. }
  7. });
  8. interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
  9. builder.addInterceptor(interceptor);//.addNetworkInterceptor(new StethoInterceptor());
  10. return builder;
  11. }

}

  1. - ServerException

public class ServerException extends Exception { private int result;// 0成功,其他失败 private int errorCode; private String message;

  1. public ServerException(int result, int errorCode, String message) {
  2. this.result = result;
  3. this.errorCode = errorCode;
  4. this.message = message;
  5. }
  6. public int getResult() {
  7. return result;
  8. }
  9. public void setResult(int result) {
  10. this.result = result;
  11. }
  12. public int getErrorCode() {
  13. return errorCode;
  14. }
  15. public void setErrorCode(int errorCode) {
  16. this.errorCode = errorCode;
  17. }
  18. @Override
  19. public String getMessage() {
  20. return message;
  21. }
  22. public void setMessage(String message) {
  23. this.message = message;
  24. }

}

  1. - 使用
  2. - ApiService
  3. ```kotlin
  4. public interface ApiService {
  5. @GET("v3/api/bluetoothkey/getCalibrateParams")
  6. Flowable<BaseBean2<PhoneModelBean>> getPhoneModel(@QueryMap Map<String, String> map);
  7. static ApiService create(){
  8. return RetrofitHelp.getInstance().create(ApiService.class);
  9. }
  10. }
  • Activity中使用

    1. ApiService.create().getPhoneModel(requestMap)
    2. .compose(RxUtils.handleBaseBean())
    3. .as(RxLife.as(this))
    4. .subscribe(new RxSubUtils<PhoneModelBean>() {
    5. @Override
    6. protected void _onNext(PhoneModelBean phoneModelBean) {
    7. }
    8. @Override
    9. protected void _onError(Throwable e, int result, String msg) {
    10. }
    11. });
    12. RetrofitHelp.getInstance().create(ApiService.class)
    13. .getPhoneModel(requestMap)
    14. .compose(RxUtils.handleBaseBean())
    15. .as(RxLife.as(this))
    16. .subscribe(new RxSubUtils<PhoneModelBean>() {
    17. @Override
    18. protected void _onNext(PhoneModelBean phoneModelBean) {
    19. Log.e("MMM", "_onNext: "+ phoneModelBean.getParams() );
    20. }
    21. @Override
    22. protected void _onError(Throwable e, int result, String msg) {
    23. Log.e("MMM", "_onError: " + result + "--" + msg + "--" + e);
    24. }
    25. });
  • 对错误统一处理封装

    • HttpCallBack ``` /**

      public abstract void onSuccess(T t);

      public void onFail(Throwable e, int result, String msg, Activity activity) { ALog.i(“HttpCallBack”, result + “——-“ + msg + “—e—“ + e.toString()); //统一处理异常 if (result == RxSubUtils.RESULT_ERROR) {

      1. //其他错误
      2. Throwable throwable = HttpHelp.unifiedError(e);
      3. CommonToast.showSettledResult(activity, false, throwable.getMessage());

      // ExceptionHandle.ResponeThrowable responeThrowable = ExceptionHandle.handleException(e); // CommonToast.showSettledResult(activity, false, responeThrowable.message); } else {

      1. //服务器返回错误
      2. if (!TextUtils.isEmpty(msg)) {
      3. CommonToast.showSettledResult(activity, false, msg);
      4. }

      } }

}

  1. - httpHelp

public class HttpHelp {

  1. public static ApiService sApiService = RetrofitHelp.getInstance().create(ApiService.class);

/**

  • 获取蓝牙标定数据 *

    • @param map
    • @param rxSubUtils /*/ public static void getPhoneModel(Map map, LifecycleOwner lifecycleOwner, RxSubUtils rxSubUtils) { //将提交的参数统一加密 setSubscribe(sApiService.

      1. getPhoneModel(MD5Util.
      2. getRequestMap(map,
      3. PhoneUtils.getToken(PublicUtils.getContext()),
      4. PhoneUtils.getPhoneID())),
      5. rxSubUtils, lifecycleOwner);

      }

      private static void setSubscribe(Flowable> flowable, RxSubUtils rxSubUtils, LifecycleOwner lifecycleOwner) { if (lifecycleOwner == null) {

      1. flowable.compose(RxUtils.handleBaseBean())
      2. .subscribe(rxSubUtils);

      } else {

      1. flowable.compose(RxUtils.handleBaseBean())
      2. .as(RxLife.as(lifecycleOwner))
      3. .subscribe(rxSubUtils);

      } }

  1. public static void getPhoneModel(Map<String, String> map, FragmentActivity activity, HttpCallBack<PhoneModelBean> httpCallBack) {
  2. //将提交的参数统一加密
  3. setSubscribe(sApiService.
  4. getPhoneModel(MD5Util.getRequestMap(map,
  5. PhoneUtils.getToken(PublicUtils.getContext()),
  6. PhoneUtils.getPhoneID())),
  7. activity, httpCallBack);
  8. }
  9. private static <T> void setSubscribe(Flowable<BaseBean2<T>> flowable, FragmentActivity activity, HttpCallBack<T> httpCallBack) {
  10. RxSubUtils<T> rxSubUtils = new RxSubUtils<T>() {
  11. @Override
  12. protected void _onNext(T t) {
  13. if (httpCallBack != null) {
  14. httpCallBack.onSuccess(t);
  15. }
  16. }
  17. @Override
  18. protected void _onError(Throwable e, int result, String msg) {
  19. if (httpCallBack != null) {
  20. httpCallBack.onFail(e, result, msg, activity);
  21. }
  22. }
  23. };
  24. if (activity == null) {
  25. flowable.compose(RxUtils.handleBaseBean())
  26. .subscribe(rxSubUtils);
  27. } else {
  28. flowable.compose(RxUtils.handleBaseBean())
  29. .as(RxLife.as(activity))
  30. .subscribe(rxSubUtils);
  31. }
  32. }

/ /*

  1. * 统一错误处理 -> 汉化了提示,以下错误出现的情况 (ps:不一定百分百按我注释的情况,可能其他情况)
  2. /*/
  3. public static Throwable unifiedError(Throwable e) {
  4. Throwable throwable = null;
  5. Context context = PublicUtils.getContext();
  6. if (!NetworkUtil.isNetworkAvailable(context)) {
  7. //无网络
  8. throwable = new Throwable(context.getString(R.string.exception_network_exception_please_check_online), e == null ? null : e.getCause());
  9. } else {
  10. if (e instanceof UnknownHostException) {
  11. //无网络的情况,或者主机挂掉了。返回,对应消息 Unable to resolve host "m.app.haosou.com": No address associated with hostname
  12. //主机挂了,也就是你服务器关了
  13. throwable = new Throwable(context.getString(R.string.exception_service_error_please_try_again), e.getCause());
  14. } else if (e instanceof SocketTimeoutException || e instanceof SocketException) {
  15. //连接超时等
  16. throwable = new Throwable(context.getString(R.string.exception_network_timeout_please_check_online), e.getCause());
  17. } else if (e instanceof IllegalArgumentException || e instanceof JsonSyntaxException) {
  18. //也就是后台返回的数据,与你本地定义的Gson类,不一致,导致解析异常 (ps:当然这不能跟客户这么说)
  19. throwable = new Throwable(context.getString(R.string.exception_failed_to_get_the_data_please_try_again_later), e.getCause());
  20. } else {
  21. //其他 未知
  22. throwable = new Throwable(context.getString(R.string.exception_unknown), e == null ? null : e.getCause());
  23. }
  24. }
  25. return throwable;
  26. }

}

  1. - 使用示例
  1. //retrofit使用示例,带生命周期处理
  2. HttpHelp.getPhoneModel(requestMap, this, new RxSubUtils<PhoneModelBean>() {
  3. @Override
  4. protected void _onNext(PhoneModelBean phoneModelBean) {
  5. ALog.i(getClass().getSimpleName(), JsonUtils.toJson(phoneModelBean));
  6. }
  7. @Override
  8. protected void _onError(Throwable e, int result, String msg) {
  9. ALog.i(getClass().getSimpleName(), result + "-----" + msg + "--e--" + e.toString());
  10. }
  11. });
  12. //retrofit使用示例,带生命周期处理
  13. HttpHelp.getPhoneModel(requestMap, this, new HttpCallBack<PhoneModelBean>() {
  14. @Override
  15. public void onSuccess(PhoneModelBean phoneModelBean) {
  16. ALog.i(getClass().getSimpleName(), JsonUtils.toJson(phoneModelBean));
  17. }
  18. //想要单独处理异常,重写此方法即可

// @Override // public void onFail(Throwable e, int result, String msg, Activity activity) { // super.onFail(e, result, msg, activity); // } });

  1. <a name="d11feb98"></a>
  2. ### Retrofit + Gson + Rxjava3 + rxlife3
  3. - 导入

//retrofit api ‘com.squareup.retrofit2:retrofit:2.9.0’ //retrofit - gson api ‘com.squareup.retrofit2:converter-gson:2.9.0’ //rxjava 相关 api ‘com.squareup.retrofit2:adapter-rxjava3:2.9.0’ //rxjava3最新版 api “io.reactivex.rxjava3:rxjava:3.0.13” api ‘io.reactivex.rxjava3:rxandroid:3.0.0’ //rxlife3 implementation ‘com.github.liujingxing.rxlife:rxlife-rxjava3:2.1.0’

  1. - 使用示例
  2. - GsonApi

interface GsonApi {

  1. companion object{
  2. val BASE_URL = "https://www.wanandroid.com/"
  3. fun create(): GsonApi {
  4. return Retrofit.Builder()
  5. .baseUrl(BASE_URL)
  6. .addConverterFactory(GsonConverterFactory.create())

// .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build() .create(GsonApi::class.java) } }

  1. @GET("wxarticle/chapters/json")
  2. fun getWxData(): Call<WxData>
  3. @GET("wxarticle/chapters/json")
  4. fun getWxData2(): Flowable<WxData>

}

  1. - Activity

GsonApi.create().getWxData2() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .life(this) .subscribe({ Log.e(TAG, “testGson: $it”) }, { Log.e(TAG, “testGson: $it”) })

  1. <a name="b54ffc07"></a>
  2. ### Retrofit + MoShi + LiveData + 协程
  3. - 导包:
  4. ```kotlin
  5. def fragment_version = "1.3.4"
  6. implementation "androidx.fragment:fragment-ktx:$fragment_version"
  7. /* implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
  8. implementation 'androidx.lifecycle:lifecycle-livedata:2.3.1'*/
  9. implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
  10. implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
  11. // implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
  12. implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
  13. //retrofit
  14. api 'com.squareup.retrofit2:retrofit:2.9.0'
  15. //retrofit-moshi
  16. implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
  17. //moshi
  18. implementation 'com.squareup.moshi:moshi:1.12.0'
  19. kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.12.0'
  • Bean

    • WxData

      1. @JsonClass(generateAdapter = true)
      2. data class WxData(
      3. var `data`: List<Data>,
      4. var errorCode: Int,
      5. var errorMsg: String
      6. )
      7. @JsonClass(generateAdapter = true)
      8. data class Data(
      9. var children: List<Any>,
      10. var courseId: Int,
      11. var id: Int,
      12. var name: String,
      13. var order: Int,
      14. var parentChapterId: Int,
      15. var userControlSetTop: Boolean,
      16. var visible: Int
      17. )
    • WxInfo `` @JsonClass(generateAdapter = true) data class WxInfo( @Json(name = "data") vardata`: List, @Json(name = “errorCode”) var errorCode: Int, @Json(name = “errorMsg”) var errorMsg: String )

@JsonClass(generateAdapter = true) data class Data2( @Json(name = “children”) var children: List, @Json(name = “courseId”) var courseId: Int, @Json(name = “id”) var id: Int, @Json(name = “name”) var name: String, @Json(name = “order”) var order: Int, @Json(name = “parentChapterId”) var parentChapterId: Int, @Json(name = “userControlSetTop”) var userControlSetTop: Boolean, @Json(name = “visible”) var visible: Int )

  1. - ViewModel

class GsonViewModel: ViewModel() {

  1. fun getWxData() = liveData {
  2. val response = withContext(Dispatchers.IO){
  3. GsonApi.create().getWxData()
  4. }
  5. emit(response)
  6. }
  7. fun getWxInfo() = liveData {
  8. val response = withContext(Dispatchers.IO){
  9. GsonApi.create().getWxInfo()
  10. }
  11. emit(response)
  12. }

}

  1. - Activity中使用

private fun liveTest() { viewModel.getWxData().observe(this){ Log.e(TAG, “liveTest: $it”) } viewModel.getWxInfo().observe(this){ Log.e(TAG, “liveTest—: $it”) } }

  1. <a name="79ffe87d"></a>
  2. ### Retrofit + Flow + MoShi + 协程
  3. - 导包
  4. ```kotlin
  5. //retrofit
  6. api 'com.squareup.retrofit2:retrofit:2.9.0'
  7. //retrofit-moshi
  8. implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
  9. //moshi
  10. implementation 'com.squareup.moshi:moshi:1.12.0'
  11. kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.12.0'
  12. //retrofit - adapter - flow
  13. implementation 'com.github.chenxyu:retrofit-adapter-flow:1.2.0'
  • Bean `` @JsonClass(generateAdapter = true) data class WxInfo( @Json(name = "data") vardata`: List, @Json(name = “errorCode”) var errorCode: Int, @Json(name = “errorMsg”) var errorMsg: String )

@JsonClass(generateAdapter = true) data class Data2( @Json(name = “children”) var children: List, @Json(name = “courseId”) var courseId: Int, @Json(name = “id”) var id: Int, @Json(name = “name”) var name: String, @Json(name = “order”) var order: Int, @Json(name = “parentChapterId”) var parentChapterId: Int, @Json(name = “userControlSetTop”) var userControlSetTop: Boolean, @Json(name = “visible”) var visible: Int )

  1. - api

interface GsonApi {

  1. companion object{
  2. val BASE_URL = "https://www.wanandroid.com/"
  3. fun create(): GsonApi {
  4. return Retrofit.Builder()
  5. .baseUrl(BASE_URL)
  6. .addConverterFactory(MoshiConverterFactory.create())

// .addConverterFactory(GsonConverterFactory.create()) // .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .addCallAdapterFactory(FlowCallAdapterFactory.create()) .build() .create(GsonApi::class.java) } }

  1. @GET("wxarticle/chapters/json")
  2. fun getWxInfoFlow(): Flow<WxInfo>

}

  1. - ViewModel

fun getWxInfoFlow() = GsonApi.create().getWxInfoFlow() .flowOn(Dispatchers.IO) .onStart { Log.e(TAG, “getWxInfoFlow: onStart”) }.onCompletion { Log.e(TAG, “getWxInfoFlow: onCompletion”) }.catch { e -> e.printStackTrace() Log.e(TAG, “getWxInfoFlow: ${e.message}”) }.asLiveData() /.collect { Log.e(TAG, “getWxInfoFlow: $it”) emit(it) }/

  1. fun getWxTest() = handlerFlow(GsonApi.create().getWxInfoFlow())
  2. private fun <T> handlerFlow(flow: Flow<T>): LiveData<T> {
  3. return flow.flowOn(Dispatchers.IO)
  4. .onStart {
  5. }.onCompletion {
  6. }.onEach {
  7. //可以在这里统一处理返回数据
  8. if (it is WxInfo){

// it.errorMsg = “this is wxinfo” //错误情况,截断,后续回到catch中 error(“this is error”) } }.catch { e -> Log.e(TAG, “handlerFlow: ${e.message}”) }.asLiveData() }

  1. - Activity使用

private fun flowTest() { / viewModel.getWxInfoFlow() .observe(this){ Log.e(TAG, “flowTest: $it”) }/ //统一处理过程测试 viewModel.getWxTest() .observe(this){ Log.e(TAG, “flowTest: $it”) } } ```

结语

最终来看,Kotlin 和 Jetpack 才是主流,最适合的还是协程和 LiveData 或 Flow,不过 Flow 这个 adapter 不确定会不会有问题,比较不是官方做的,有待检验,最稳妥的做法还是使用 LiveData。