Retrofit+OkHttp+ViewModel

打印 上一主题 下一主题

主题 871|帖子 871|积分 2613

目录
中规中矩的 Retrofit+OkHttp+ViewModel 使用介绍。
为什么选择 LiveData、Retrofit 和 OkHttp?
项目依赖
配置 OkHttpClient 和 Retrofit
创建数据模型和 API 接口
创建 Repository 类
创建 ViewModel 类
在 Activity 中使用 ViewModel 和 LiveData
Mvvm模式使用,下面应该算是一个完整封装框架。
Retrofit Xml本领
1. 添加必要的依赖项
2. 创建数据模型
3. 创建 API 接口
4. 配置 Retrofit 实例
5. 发起哀求



中规中矩的 Retrofit+OkHttp+ViewModel 使用介绍。

在现代 Android 开发中,使用 LiveData、Retrofit 和 OkHttp 进行网络哀求和数据处理已经成为一种标准做法。这篇博文将详细介绍如何将这三者结合起来,构建一个高效、可维护的网络哀求框架。
为什么选择 LiveData、Retrofit 和 OkHttp?



  • LiveData:LiveData 是一种可观察的数据持有者类,具有生命周期感知本领。它能与 Android 的生命周期组件无缝集成,确保 UI 组件只在活泼状态下更新,从而避免内存泄漏和崩溃问题。
  • Retrofit:Retrofit 是一个强大的类型安全的 HTTP 客户端,用于 Android 和 Java。它简化了网络哀求的创建和处理过程,支持多种数据转换器(如 Gson、SimpleXML),并与 OkHttp 无缝集成。
  • OkHttp:OkHttp 是一个高效的 HTTP 客户端,支持毗连池、缓存、重定向和失败重试等功能。它为 Retrofit 提供了底层支持,而且可以通过拦截器进行机动的哀求和响应处理。
项目依赖

起首,在你的 build.gradle 文件中添加以下依赖项:
  1. dependencies {
  2.     implementation 'com.squareup.retrofit2:retrofit:2.9.0'
  3.     implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
  4.     implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
  5.     implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
  6.     implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
  7. }
复制代码
配置 OkHttpClient 和 Retrofit

创建一个 ApiClient 类来配置 OkHttpClient 和 Retrofit 实例:
  1. public class ApiClient {
  2.     private static final String BASE_URL = "https://api.example.com/";
  3.     private static Retrofit retrofit = null;
  4.     public static Retrofit getClient() {
  5.         if (retrofit == null) {
  6.             HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
  7.             logging.setLevel(HttpLoggingInterceptor.Level.BODY);
  8.             
  9.             OkHttpClient client = new OkHttpClient.Builder()
  10.                     .addInterceptor(logging)
  11.                     .build();
  12.             retrofit = new Retrofit.Builder()
  13.                     .baseUrl(BASE_URL)
  14.                     .client(client)
  15.                     .addConverterFactory(GsonConverterFactory.create())
  16.                     .build();
  17.         }
  18.         return retrofit;
  19.     }
  20. }
复制代码
创建数据模型和 API 接口

界说一个数据模型类和一个 API 接口来描述网络哀求:
  1. public class User {
  2.     @SerializedName("id")
  3.     private int id;
  4.     @SerializedName("name")
  5.     private String name;
  6.     @SerializedName("email")
  7.     private String email;
  8.     // Getters and Setters
  9. }
复制代码
  1. public interface ApiService {
  2.     @GET("users")
  3.     Call<List<User>> getUsers();
  4. }
复制代码
创建 Repository 类

创建一个 UserRepository 类来管理数据操作:
  1. public class UserRepository {
  2.     private ApiService apiService;
  3.     public UserRepository() {
  4.         apiService = ApiClient.getClient().create(ApiService.class);
  5.     }
  6.     public LiveData<List<User>> getUsers() {
  7.         final MutableLiveData<List<User>> data = new MutableLiveData<>();
  8.         apiService.getUsers().enqueue(new Callback<List<User>>() {
  9.             @Override
  10.             public void onResponse(Call<List<User>> call, Response<List<User>> response) {
  11.                 if (response.isSuccessful()) {
  12.                     data.setValue(response.body());
  13.                 }
  14.             }
  15.             @Override
  16.             public void onFailure(Call<List<User>> call, Throwable t) {
  17.                 data.setValue(null);
  18.             }
  19.         });
  20.         return data;
  21.     }
  22. }
复制代码
创建 ViewModel 类

  1. public class UserViewModel extends ViewModel {
  2.     private UserRepository userRepository;
  3.     private LiveData<List<User>> users;
  4.     public UserViewModel() {
  5.         userRepository = new UserRepository();
  6.         users = userRepository.getUsers();
  7.     }
  8.     public LiveData<List<User>> getUsers() {
  9.         return users;
  10.     }
  11. }
复制代码
在 Activity 中使用 ViewModel 和 LiveData

在 Activity 中使用 ViewModel 和 LiveData 来观察数据厘革:
  1. public class MainActivity extends AppCompatActivity {
  2.     private UserViewModel userViewModel;
  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         setContentView(R.layout.activity_main);
  7.         userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
  8.         userViewModel.getUsers().observe(this, new Observer<List<User>>() {
  9.             @Override
  10.             public void onChanged(List<User> users) {
  11.                 // Update UI with the list of users
  12.             }
  13.         });
  14.     }
  15. }
复制代码
通过这些步骤,你可以在 Android 项目中使用 LiveData 与 Retrofit 和 OkHttp 来实现网络哀求框架,并将数据绑定到 UI。这种架构筹划不仅进步了代码的可读性和可维护性,还能有用地管理网络哀求和数据更新。
以上就是基本使用,如果你有点追求,就是共同框架使用网络本领。
Mvvm模式使用,下面应该算是一个完整封装框架。

  1. public class MainActivity extends BaseMvvmAc<AcMainBinding, HomeViewModel>  {
  2.   @Override
  3.     protected int initContentView(Bundle savedInstanceState) {
  4.         return R.layout.ac_main;
  5.     }
  6.     @Override
  7.     protected int initVariableId() {
  8.         return BR.viewModel;
  9.     }
  10. }
复制代码
  1. public abstract class BaseMvvmAc<V extends ViewDataBinding, VM extends BaseViewModel> extends BaseAc {
  2.     protected VM viewModel;
  3.     protected V binding;
  4.   private void initViewDataBinding(Bundle savedInstanceState) {
  5.         binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState));
  6.         if (viewModel == null) {
  7.             Class modelClass;
  8.             Type type = getClass().getGenericSuperclass();
  9.             if (type instanceof ParameterizedType) {
  10.                 modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
  11.             } else {
  12.                 //如果没有指定泛型参数,则默认使用BaseViewModel
  13.                 modelClass = BaseViewModel.class;
  14.             }
  15.             viewModel = (VM) new ViewModelProvider(this,
  16.                     ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()))
  17.                     .get(modelClass);
  18.         }
  19.         if (initVariableId() > 0) {
  20.             binding.setVariable(initVariableId(), viewModel);
  21.         }
  22.         viewModel.uiChangeLiveData().onBackPressedEvent().observe(this, o -> {
  23.             onBackPressed();
  24.         });
  25.     }
  26.     /**
  27.      * 初始化根布局
  28.      *
  29.      * @param savedInstanceState
  30.      * @return 布局layout的id
  31.      */
  32.     protected abstract int initContentView(Bundle savedInstanceState);
  33.     /**
  34.      * 初始化ViewModel的id
  35.      *
  36.      * @return BR的id
  37.      */
  38.     protected abstract int initVariableId();
  39. }
复制代码

  • 设置布局并获取布局实例。
  • 检查viewModel是否为空,如果为空则根据泛型参数创建对应的ViewModel实例。
  • 如果指定了ViewModel的BR id,则将ViewModel绑定到布局中。
  • 监听ViewModel中的返回按键变乱,触发onBackPressed方法。
  1. public class HomeViewModel extends BaseViewModel<HomeRepository> {
  2.     public HomeViewModel(@NonNull Application application) {
  3.         super(application);
  4.     }
  5. }
复制代码
  1. public class BaseViewModel<M extends BaseModel> extends AndroidViewModel implements IBaseViewModel, Consumer<Disposable> {
  2.     private UiChangeLiveData uiChangeLiveData;
  3.     private CompositeDisposable mCompositeDisposable;
  4.     protected M model;
  5.     public BaseViewModel(@NonNull Application application) {
  6.         super(application);
  7.         model = createModel();
  8.     }
  9.     private M createModel() {
  10.         try {
  11.             Type superClass = getClass().getGenericSuperclass();
  12.             Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
  13.             Class<?> clazz = getRawType(type);
  14.             return (M) clazz.newInstance();
  15.         } catch (Exception e) {
  16.             e.printStackTrace();
  17.         }
  18.         return null;
  19.     }
  20. //获取当前类的父类类型。
  21. //获取父类的第一个泛型参数类型。
  22. //将该类型转换为具体的类类型。
  23. //使用 newInstance 方法创建该类的实例并返回。
  24. //如果过程中出现异常,则打印堆栈信息并返回 null。
  25.     // type不能直接实例化对象,通过type获取class的类型,然后实例化对象
  26.     private Class<?> getRawType(Type type) {
  27.         if (type instanceof Class) {
  28.             return (Class) type;
  29.         } else if (type instanceof ParameterizedType) {
  30.             ParameterizedType parameterizedType = (ParameterizedType) type;
  31.             Type rawType = parameterizedType.getRawType();
  32.             return (Class) rawType;
  33.         } else if (type instanceof GenericArrayType) {
  34.             Type componentType = ((GenericArrayType) type).getGenericComponentType();
  35.             return Array.newInstance(getRawType(componentType), 0).getClass();
  36.         } else if (type instanceof TypeVariable) {
  37.             return Object.class;
  38.         } else if (type instanceof WildcardType) {
  39.             return getRawType(((WildcardType) type).getUpperBounds()[0]);
  40.         } else {
  41.             String className = type == null ? "null" : type.getClass().getName();
  42.             throw new IllegalArgumentException("Expected a Class, ParameterizedType, or GenericArrayType, but <" + type + "> is of type " + className);
  43.         }
  44.     }
  45.     protected void addDisposable(Disposable disposable) {
  46.         if (this.mCompositeDisposable == null) {
  47.             this.mCompositeDisposable = new CompositeDisposable();
  48.         }
  49.         this.mCompositeDisposable.add(disposable);
  50.     }
  51.     public UiChangeLiveData uiChangeLiveData() {
  52.         if (uiChangeLiveData == null) {
  53.             uiChangeLiveData = new UiChangeLiveData();
  54.         }
  55.         return uiChangeLiveData;
  56.     }
  57.     @Override
  58.     protected void onCleared() {
  59.         super.onCleared();
  60.         if (mCompositeDisposable != null && !mCompositeDisposable.isDisposed()) {
  61.             mCompositeDisposable.clear();
  62.         }
  63.         if (model != null) {
  64.             model.onCleared();
  65.         }
  66.     }
  67.     @Override
  68.     public void onAny(LifecycleOwner owner, Lifecycle.Event event) {
  69.     }
  70.     @Override
  71.     public void onCreate() {
  72.     }
  73.     @Override
  74.     public void onDestroy() {
  75.     }
  76.     @Override
  77.     public void onStart() {
  78.     }
  79.     @Override
  80.     public void onStop() {
  81.     }
  82.     @Override
  83.     public void onResume() {
  84.     }
  85.     @Override
  86.     public void onPause() {
  87.     }
  88.     @Override
  89.     public void accept(Disposable disposable) throws Exception {
  90.         addDisposable(disposable);
  91.     }
  92.     public void onBackPressed() {
  93.         uiChangeLiveData.onBackPressedEvent.call();
  94.     }
  95.     public final class UiChangeLiveData extends SingleLiveEvent {
  96.         private SingleLiveEvent<Void> onBackPressedEvent;
  97.         public SingleLiveEvent<Void> onBackPressedEvent() {
  98.             return onBackPressedEvent = createLiveData(onBackPressedEvent);
  99.         }
  100.         private <T> SingleLiveEvent<T> createLiveData(SingleLiveEvent<T> liveData) {
  101.             if (liveData == null) {
  102.                 liveData = new SingleLiveEvent<>();
  103.             }
  104.             return liveData;
  105.         }
  106.     }
  107. }
复制代码
  1. public class HomeRepository extends BaseModel {
  2.     public void unCollect(String id, ApiCallback<Object> callback) {
  3.         ApiUtil.getArticleApi().unCollect(id).enqueue(callback);
  4.     }
  5. }
复制代码
  1. /**
  2. * Description: 不同模块BASE_URL可能不同
  3. */
  4. public class ApiUtil {
  5.     public static ProjectApi getProjectApi() {
  6.         return RetrofitCreateHelper.getInstance().create(U.BASE_URL, ProjectApi.class);
  7.     }
  8. }
复制代码
  1. public interface ProjectApi {
  2.     /**
  3.      * 项目分类
  4.      *
  5.      * @return
  6.      */
  7.     @RetryCount(value = 3)
  8.     @GET("project/tree/json")
  9.     ApiCall<List<ProjectListRes>> listProjectsTab();
  10. }
复制代码
  1. public class ApiCall <R> {
  2.     private final Observable<Response<ApiResponse<R>>> mEnqueueObservable;
  3.     private int mRetryCount;
  4.     private long mRetryDelay;
  5.     private long mRetryIncreaseDelay;
  6.     private Disposable mDisposable;
  7.     private Call<ApiResponse<R>> mCall;
  8.     ApiCall(Annotation[] annotations, Call<ApiResponse<R>> call) {
  9.         mCall = call;
  10.         mEnqueueObservable = RxJavaPlugins.onAssembly(new CallEnqueueObservable<>(call));
  11.         for (Annotation annotation : annotations) {
  12.             Class<? extends Annotation> clazz = annotation.annotationType();
  13.             if (clazz == RetryCount.class) {
  14.                 RetryCount retryCount = (RetryCount) annotation;
  15.                 mRetryCount = retryCount.value();
  16.             } else if (clazz == RetryDelay.class) {
  17.                 RetryDelay retryDelay = (RetryDelay) annotation;
  18.                 mRetryDelay = retryDelay.value();
  19.             } else if (clazz == RetryIncreaseDelay.class) {
  20.                 RetryIncreaseDelay retryIncreaseDelay = (RetryIncreaseDelay) annotation;
  21.                 mRetryIncreaseDelay = retryIncreaseDelay.value();
  22.             }
  23.         }
  24.     }
  25.     /**
  26.      * 进入请求队列
  27.      * 不绑定activity生命周期
  28.      * 建议使用传入activity的方式,以绑定生命周期
  29.      *
  30.      * @param callback 请求回调
  31.      */
  32.     public <T extends ApiCallback<R>> void enqueue(T callback) {
  33.         enqueue(null, ProgressType.NONE, false, callback);
  34.     }
  35.     /**
  36.      * 进入请求队列
  37.      * 不绑定activity生命周期
  38.      * 建议使用传入activity的方式,以绑定生命周期
  39.      *
  40.      * @param callback 请求回调
  41.      */
  42.     public <T extends ApiCallback<R>> void enqueue(T callback, ProgressType type) {
  43.         enqueue(null, type, false, callback);
  44.     }
  45.     /**
  46.      * 进入请求队列
  47.      * 无进度框,无toast
  48.      * 自动绑定activity生命周期
  49.      *
  50.      * @param callback 请求回调
  51.      */
  52.     public void enqueue(Context activity, final ApiCallback<R> callback) {
  53.         enqueue(activity, ProgressType.NONE, false, callback);
  54.     }
  55.     /**
  56.      * 进入请求队列
  57.      * 带可取消进度框,有toast
  58.      * 自动绑定activity生命周期
  59.      *
  60.      * @param callback 请求回调
  61.      */
  62.     public void enqueue2(Context activity, final ApiCallback<R> callback) {
  63.         enqueue(activity, ProgressType.CANCELABLE, true, callback);
  64.     }
  65.     /**
  66.      * 进入请求队列
  67.      *
  68.      * @param activity     界面
  69.      * @param progressType 进度框类型
  70.      * @param callback     请求回调
  71.      */
  72.     public void enqueue(Context activity, ProgressType progressType, final ApiCallback<R> callback) {
  73.         enqueue(activity, progressType, false, callback);
  74.     }
  75.     /**
  76.      * 进入请求队列
  77.      *
  78.      * @param activity   界面
  79.      * @param toastError 是否弹错误toast
  80.      * @param callback   请求回调
  81.      */
  82.     public void enqueue(Context activity, boolean toastError, final ApiCallback<R> callback) {
  83.         enqueue(activity, ProgressType.NONE, toastError, callback);
  84.     }
  85.     /**
  86.      * 进入请求队列
  87.      *
  88.      * @param activity     界面
  89.      * @param progressType 进度框类型
  90.      * @param toastError   是否弹错误toast
  91.      * @param callback     请求回调
  92.      */
  93.     public void enqueue(Context activity, ProgressType progressType, final boolean toastError,
  94.                         final ApiCallback<R> callback) {
  95.         Observable<Response<ApiResponse<R>>> observable;
  96.         /*if (activity instanceof RxAppCompatActivity) {
  97.             RxAppCompatActivity rxAppCompatActivity = (RxAppCompatActivity) activity;
  98.             observable = mEnqueueObservable.compose(rxAppCompatActivity.<Response<ApiResponse<R>>>bindToLifecycle());
  99.         } else {
  100.             observable = mEnqueueObservable;
  101.         }*/
  102.         observable = mEnqueueObservable;
  103.         mDisposable = observable.retryWhen(new RetryHandler<R>(mRetryCount, mRetryDelay, mRetryIncreaseDelay))
  104.                 .subscribeOn(Schedulers.io())
  105.                 .doOnSubscribe(new Consumer<Disposable>() {
  106.                     @Override
  107.                     public void accept(Disposable disposable) throws Exception {
  108.                         callback.onStart();
  109.                     }
  110.                 })
  111.                 .subscribeOn(AndroidSchedulers.mainThread())
  112.                 .observeOn(AndroidSchedulers.mainThread())
  113.                 .subscribe(new Consumer<Response<ApiResponse<R>>>() {
  114.                     @Override
  115.                     public void accept(Response<ApiResponse<R>> response) throws Exception {
  116.                         ApiResponse<R> body = response.body();
  117.                         if (!response.isSuccessful() || body == null) {
  118.                             onError(callback, new HttpException(response), toastError);
  119.                             cancel();
  120.                             return;
  121.                         }
  122.                         callback.onSuccess(body);
  123.                         cancel();
  124.                     }
  125.                 }, new Consumer<Throwable>() {
  126.                     @Override
  127.                     public void accept(Throwable throwable) throws Exception {
  128.                         onError(callback, throwable, toastError);
  129.                         cancel();
  130.                     }
  131.                 });
  132.     }
  133.     /**
  134.      * Synchronously send the request and return its response.
  135.      *
  136.      * @throws IOException if a problem occurred talking to the server.
  137.      */
  138.     public Response<ApiResponse<R>> exectue() throws IOException {
  139.         return mCall.clone().execute();
  140.     }
  141.     /**
  142.      * 处理错误
  143.      *
  144.      * @param callback  回调
  145.      * @param throwable 错误
  146.      */
  147.     private void onError(ApiCallback<R> callback, Throwable throwable, boolean toast) {
  148.         callback.onError(throwable);
  149.     }
  150.     public void cancel() {
  151.         if (mDisposable != null) {
  152.             mDisposable.dispose();
  153.         }
  154.     }
  155.     /**
  156.      * 进度条类型
  157.      */
  158.     public enum ProgressType {
  159.         /**
  160.          * 无进度条
  161.          */
  162.         NONE,
  163.         /**
  164.          * 可取消进度条
  165.          */
  166.         CANCELABLE,
  167.         /**
  168.          * 不可取消进度条
  169.          */
  170.         UN_CANCELABLE
  171.     }
  172. }
复制代码
从使用角度,直接copy以上的代码就可以。
Retrofit Xml本领

1. 添加必要的依赖项

起首,在你的 build.gradle 文件中添加 Retrofit 和转换器的依赖项:
  1. dependencies {
  2.     implementation 'com.squareup.retrofit2:converter-simplexml:2.9.0'
  3. }
复制代码
2. 创建数据模型

创建一个数据模型类,它将被转换为 XML 格式:
  1. @Root(name = "restrict")
  2. public class Restrict {
  3.     @Attribute(name = "Type")
  4.     private int type;
  5.     // Constructor
  6.     public Restrict(int type) {
  7.         this.type = type;
  8.     }
  9.     // Getter and Setter
  10.     public int getType() {
  11.         return type;
  12.     }
  13.     public void setType(int type) {
  14.         this.type = type;
  15.     }
  16. }
复制代码
3. 创建 API 接口

界说一个接口来描述你的 API 端点:
  1. public interface ApiService {
  2.     @Headers({
  3.         "Content-Type: application/xml",
  4.     })
  5.     @POST("xxxx")
  6.     Call<Void> sendRestrict(@Body Restrict restrict);
  7. }
复制代码
4. 配置 Retrofit 实例

配置 Retrofit 实例并创建 API 服务:
  1. public class RetrofitClient {
  2.     private static final String BASE_URL = "xxxxxxxxx";
  3.     private static Retrofit retrofit = null;
  4.     public static Retrofit getClient() {
  5.         if (retrofit == null) {
  6.             retrofit = new Retrofit.Builder()
  7.                 .baseUrl(BASE_URL)
  8.                 .addConverterFactory(SimpleXmlConverterFactory.create())
  9.                 .build();
  10.         }
  11.         return retrofit;
  12.     }
  13.     public static ApiService getApiService() {
  14.         return getClient().create(ApiService.class);
  15.     }
  16. }
复制代码
5. 发起哀求

最后,使用创建的 ApiService 发起哀求:
  1. public class MainActivity extends AppCompatActivity {
  2.     @Override
  3.     protected void onCreate(Bundle savedInstanceState) {
  4.         super.onCreate(savedInstanceState);
  5.         setContentView(R.layout.activity_main);
  6.         ApiService apiService = RetrofitClient.getApiService();
  7.                 String xmlData = "";
  8.         MediaType xmlMediaType = MediaType.parse("application/xml");
  9.         RequestBody xmlBody = RequestBody.create(xmlData, xmlMediaType);
  10.         Call<Void> call = apiService.sendRestrict(xmlBody);
  11.         call.enqueue(new Callback<Void>() {
  12.             @Override
  13.             public void onResponse(Call<Void> call, Response<Void> response) {
  14.                 if (response.isSuccessful()) {
  15.                     Log.d("MainActivity", "Request successful");
  16.                 } else {
  17.                     Log.e("MainActivity", "Request failed");
  18.                 }
  19.             }
  20.             @Override
  21.             public void onFailure(Call<Void> call, Throwable t) {
  22.                 Log.e("MainActivity", "Error: " + t.getMessage());
  23.             }
  24.         });
  25.     }
  26. }
复制代码
XML哀求本领重要就两点:
1、添加内置的 simplexml 依赖,添加Retrofit转换器  .addConverterFactory(SimpleXmlConverterFactory.create())
2、使用 MediaType.parse 方法界说哀求体的媒体类型为 application/xml

比较简单,但是我还是在这个功能上泯灭了两个小时时间差点翻车,重要是几个同事需要立即使用。按照步骤死活无法乐成,
我使用的方式是 bean转 xml 哀求。
  1.         String xml = "<xxx></xxx>";
  2.         Serializer serializer = new Persister();
  3.         Restrict restrict = serializer.read(Restrict.class, xml);
复制代码
我甚至猜疑接口是错误的,都没有猜疑这种方式有问题,用终端跑一下,乐成返回数据。
然后猜疑参数问题,猜疑网络问题都没有猜疑如许的写法有什么问题。最后没办法给Okhttp添加了拦截器打印哀求参数,发现 为啥是 json形式哀求?说实在的至今没搞清晰为什么~
  1.            String xmlData = "";
  2.         MediaType xmlMediaType = MediaType.parse("application/xml");
  3.         RequestBody xmlBody = RequestBody.create(xmlData, xmlMediaType);
复制代码
  1.         if (request.body() != null && request.body().contentType() != null) {
  2.             MediaType contentType = request.body().contentType();
  3.             if (contentType.subtype().equals("xml") || contentType.subtype().equals("json")) {
  4.                 Buffer buffer = new Buffer();
  5.                 request.body().writeTo(buffer);
  6.                 Log.e(TAG,"Request body (" + contentType + "): " + buffer.readUtf8());
  7.             }
  8.         }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表