当前位置: 首页 > wzjs >正文

公益网站建设分析app网站平台搭建

公益网站建设分析,app网站平台搭建,做网站卖钱,人力资源公司注册条件目录 中规中矩的 RetrofitOkHttpViewModel 使用介绍。 为什么选择 LiveData、Retrofit 和 OkHttp? 项目依赖 配置 OkHttpClient 和 Retrofit 创建数据模型和 API 接口 创建 Repository 类 创建 ViewModel 类 在 Activity 中使用 ViewModel 和 LiveData Mvv…

目录

中规中矩的 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 文件中添加以下依赖项:

dependencies {implementation 'com.squareup.retrofit2:retrofit:2.9.0'implementation 'com.squareup.retrofit2:converter-gson:2.9.0'implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
}

配置 OkHttpClient 和 Retrofit

创建一个 ApiClient 类来配置 OkHttpClient 和 Retrofit 实例:

public class ApiClient {private static final String BASE_URL = "https://api.example.com/";private static Retrofit retrofit = null;public static Retrofit getClient() {if (retrofit == null) {HttpLoggingInterceptor logging = new HttpLoggingInterceptor();logging.setLevel(HttpLoggingInterceptor.Level.BODY);OkHttpClient client = new OkHttpClient.Builder().addInterceptor(logging).build();retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(client).addConverterFactory(GsonConverterFactory.create()).build();}return retrofit;}
}

创建数据模型和 API 接口

定义一个数据模型类和一个 API 接口来描述网络请求:

public class User {@SerializedName("id")private int id;@SerializedName("name")private String name;@SerializedName("email")private String email;// Getters and Setters
}
public interface ApiService {@GET("users")Call<List<User>> getUsers();
}

创建 Repository 类

创建一个 UserRepository 类来管理数据操作:

public class UserRepository {private ApiService apiService;public UserRepository() {apiService = ApiClient.getClient().create(ApiService.class);}public LiveData<List<User>> getUsers() {final MutableLiveData<List<User>> data = new MutableLiveData<>();apiService.getUsers().enqueue(new Callback<List<User>>() {@Overridepublic void onResponse(Call<List<User>> call, Response<List<User>> response) {if (response.isSuccessful()) {data.setValue(response.body());}}@Overridepublic void onFailure(Call<List<User>> call, Throwable t) {data.setValue(null);}});return data;}
}

创建 ViewModel 类

public class UserViewModel extends ViewModel {private UserRepository userRepository;private LiveData<List<User>> users;public UserViewModel() {userRepository = new UserRepository();users = userRepository.getUsers();}public LiveData<List<User>> getUsers() {return users;}
}

在 Activity 中使用 ViewModel 和 LiveData

在 Activity 中使用 ViewModel 和 LiveData 来观察数据变化:

public class MainActivity extends AppCompatActivity {private UserViewModel userViewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);userViewModel = new ViewModelProvider(this).get(UserViewModel.class);userViewModel.getUsers().observe(this, new Observer<List<User>>() {@Overridepublic void onChanged(List<User> users) {// Update UI with the list of users}});}
}

通过这些步骤,你可以在 Android 项目中使用 LiveData 与 Retrofit 和 OkHttp 来实现网络请求框架,并将数据绑定到 UI。这种架构设计不仅提高了代码的可读性和可维护性,还能有效地管理网络请求和数据更新。

以上就是基本使用,如果你有点追求,就是配合框架使用网络能力。

Mvvm模式使用,下面应该算是一个完整封装框架。

public class MainActivity extends BaseMvvmAc<AcMainBinding, HomeViewModel>  {@Overrideprotected int initContentView(Bundle savedInstanceState) {return R.layout.ac_main;}@Overrideprotected int initVariableId() {return BR.viewModel;}
}
public abstract class BaseMvvmAc<V extends ViewDataBinding, VM extends BaseViewModel> extends BaseAc {protected VM viewModel;protected V binding;private void initViewDataBinding(Bundle savedInstanceState) {binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState));if (viewModel == null) {Class modelClass;Type type = getClass().getGenericSuperclass();if (type instanceof ParameterizedType) {modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];} else {//如果没有指定泛型参数,则默认使用BaseViewModelmodelClass = BaseViewModel.class;}viewModel = (VM) new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(modelClass);}if (initVariableId() > 0) {binding.setVariable(initVariableId(), viewModel);}viewModel.uiChangeLiveData().onBackPressedEvent().observe(this, o -> {onBackPressed();});}/*** 初始化根布局** @param savedInstanceState* @return 布局layout的id*/protected abstract int initContentView(Bundle savedInstanceState);/*** 初始化ViewModel的id** @return BR的id*/protected abstract int initVariableId();}
  1. 设置布局并获取布局实例。
  2. 检查viewModel是否为空,如果为空则根据泛型参数创建对应的ViewModel实例。
  3. 如果指定了ViewModel的BR id,则将ViewModel绑定到布局中。
  4. 监听ViewModel中的返回按键事件,触发onBackPressed方法。
public class HomeViewModel extends BaseViewModel<HomeRepository> {public HomeViewModel(@NonNull Application application) {super(application);}
}
public class BaseViewModel<M extends BaseModel> extends AndroidViewModel implements IBaseViewModel, Consumer<Disposable> {private UiChangeLiveData uiChangeLiveData;private CompositeDisposable mCompositeDisposable;protected M model;public BaseViewModel(@NonNull Application application) {super(application);model = createModel();}private M createModel() {try {Type superClass = getClass().getGenericSuperclass();Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];Class<?> clazz = getRawType(type);return (M) clazz.newInstance();} catch (Exception e) {e.printStackTrace();}return null;}
//获取当前类的父类类型。
//获取父类的第一个泛型参数类型。
//将该类型转换为具体的类类型。
//使用 newInstance 方法创建该类的实例并返回。
//如果过程中出现异常,则打印堆栈信息并返回 null。// type不能直接实例化对象,通过type获取class的类型,然后实例化对象private Class<?> getRawType(Type type) {if (type instanceof Class) {return (Class) type;} else if (type instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) type;Type rawType = parameterizedType.getRawType();return (Class) rawType;} else if (type instanceof GenericArrayType) {Type componentType = ((GenericArrayType) type).getGenericComponentType();return Array.newInstance(getRawType(componentType), 0).getClass();} else if (type instanceof TypeVariable) {return Object.class;} else if (type instanceof WildcardType) {return getRawType(((WildcardType) type).getUpperBounds()[0]);} else {String className = type == null ? "null" : type.getClass().getName();throw new IllegalArgumentException("Expected a Class, ParameterizedType, or GenericArrayType, but <" + type + "> is of type " + className);}}protected void addDisposable(Disposable disposable) {if (this.mCompositeDisposable == null) {this.mCompositeDisposable = new CompositeDisposable();}this.mCompositeDisposable.add(disposable);}public UiChangeLiveData uiChangeLiveData() {if (uiChangeLiveData == null) {uiChangeLiveData = new UiChangeLiveData();}return uiChangeLiveData;}@Overrideprotected void onCleared() {super.onCleared();if (mCompositeDisposable != null && !mCompositeDisposable.isDisposed()) {mCompositeDisposable.clear();}if (model != null) {model.onCleared();}}@Overridepublic void onAny(LifecycleOwner owner, Lifecycle.Event event) {}@Overridepublic void onCreate() {}@Overridepublic void onDestroy() {}@Overridepublic void onStart() {}@Overridepublic void onStop() {}@Overridepublic void onResume() {}@Overridepublic void onPause() {}@Overridepublic void accept(Disposable disposable) throws Exception {addDisposable(disposable);}public void onBackPressed() {uiChangeLiveData.onBackPressedEvent.call();}public final class UiChangeLiveData extends SingleLiveEvent {private SingleLiveEvent<Void> onBackPressedEvent;public SingleLiveEvent<Void> onBackPressedEvent() {return onBackPressedEvent = createLiveData(onBackPressedEvent);}private <T> SingleLiveEvent<T> createLiveData(SingleLiveEvent<T> liveData) {if (liveData == null) {liveData = new SingleLiveEvent<>();}return liveData;}}
}
public class HomeRepository extends BaseModel {public void unCollect(String id, ApiCallback<Object> callback) {ApiUtil.getArticleApi().unCollect(id).enqueue(callback);}}
/*** Description: 不同模块BASE_URL可能不同*/
public class ApiUtil {public static ProjectApi getProjectApi() {return RetrofitCreateHelper.getInstance().create(U.BASE_URL, ProjectApi.class);}}
public interface ProjectApi {/*** 项目分类** @return*/@RetryCount(value = 3)@GET("project/tree/json")ApiCall<List<ProjectListRes>> listProjectsTab();}
public class ApiCall <R> {private final Observable<Response<ApiResponse<R>>> mEnqueueObservable;private int mRetryCount;private long mRetryDelay;private long mRetryIncreaseDelay;private Disposable mDisposable;private Call<ApiResponse<R>> mCall;ApiCall(Annotation[] annotations, Call<ApiResponse<R>> call) {mCall = call;mEnqueueObservable = RxJavaPlugins.onAssembly(new CallEnqueueObservable<>(call));for (Annotation annotation : annotations) {Class<? extends Annotation> clazz = annotation.annotationType();if (clazz == RetryCount.class) {RetryCount retryCount = (RetryCount) annotation;mRetryCount = retryCount.value();} else if (clazz == RetryDelay.class) {RetryDelay retryDelay = (RetryDelay) annotation;mRetryDelay = retryDelay.value();} else if (clazz == RetryIncreaseDelay.class) {RetryIncreaseDelay retryIncreaseDelay = (RetryIncreaseDelay) annotation;mRetryIncreaseDelay = retryIncreaseDelay.value();}}}/*** 进入请求队列* 不绑定activity生命周期* 建议使用传入activity的方式,以绑定生命周期** @param callback 请求回调*/public <T extends ApiCallback<R>> void enqueue(T callback) {enqueue(null, ProgressType.NONE, false, callback);}/*** 进入请求队列* 不绑定activity生命周期* 建议使用传入activity的方式,以绑定生命周期** @param callback 请求回调*/public <T extends ApiCallback<R>> void enqueue(T callback, ProgressType type) {enqueue(null, type, false, callback);}/*** 进入请求队列* 无进度框,无toast* 自动绑定activity生命周期** @param callback 请求回调*/public void enqueue(Context activity, final ApiCallback<R> callback) {enqueue(activity, ProgressType.NONE, false, callback);}/*** 进入请求队列* 带可取消进度框,有toast* 自动绑定activity生命周期** @param callback 请求回调*/public void enqueue2(Context activity, final ApiCallback<R> callback) {enqueue(activity, ProgressType.CANCELABLE, true, callback);}/*** 进入请求队列** @param activity     界面* @param progressType 进度框类型* @param callback     请求回调*/public void enqueue(Context activity, ProgressType progressType, final ApiCallback<R> callback) {enqueue(activity, progressType, false, callback);}/*** 进入请求队列** @param activity   界面* @param toastError 是否弹错误toast* @param callback   请求回调*/public void enqueue(Context activity, boolean toastError, final ApiCallback<R> callback) {enqueue(activity, ProgressType.NONE, toastError, callback);}/*** 进入请求队列** @param activity     界面* @param progressType 进度框类型* @param toastError   是否弹错误toast* @param callback     请求回调*/public void enqueue(Context activity, ProgressType progressType, final boolean toastError,final ApiCallback<R> callback) {Observable<Response<ApiResponse<R>>> observable;/*if (activity instanceof RxAppCompatActivity) {RxAppCompatActivity rxAppCompatActivity = (RxAppCompatActivity) activity;observable = mEnqueueObservable.compose(rxAppCompatActivity.<Response<ApiResponse<R>>>bindToLifecycle());} else {observable = mEnqueueObservable;}*/observable = mEnqueueObservable;mDisposable = observable.retryWhen(new RetryHandler<R>(mRetryCount, mRetryDelay, mRetryIncreaseDelay)).subscribeOn(Schedulers.io()).doOnSubscribe(new Consumer<Disposable>() {@Overridepublic void accept(Disposable disposable) throws Exception {callback.onStart();}}).subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Response<ApiResponse<R>>>() {@Overridepublic void accept(Response<ApiResponse<R>> response) throws Exception {ApiResponse<R> body = response.body();if (!response.isSuccessful() || body == null) {onError(callback, new HttpException(response), toastError);cancel();return;}callback.onSuccess(body);cancel();}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {onError(callback, throwable, toastError);cancel();}});}/*** Synchronously send the request and return its response.** @throws IOException if a problem occurred talking to the server.*/public Response<ApiResponse<R>> exectue() throws IOException {return mCall.clone().execute();}/*** 处理错误** @param callback  回调* @param throwable 错误*/private void onError(ApiCallback<R> callback, Throwable throwable, boolean toast) {callback.onError(throwable);}public void cancel() {if (mDisposable != null) {mDisposable.dispose();}}/*** 进度条类型*/public enum ProgressType {/*** 无进度条*/NONE,/*** 可取消进度条*/CANCELABLE,/*** 不可取消进度条*/UN_CANCELABLE}
}

从使用角度,直接copy以上的代码就可以。

Retrofit Xml能力

1. 添加必要的依赖项

首先,在你的 build.gradle 文件中添加 Retrofit 和转换器的依赖项:

dependencies {implementation 'com.squareup.retrofit2:converter-simplexml:2.9.0'
}

2. 创建数据模型

创建一个数据模型类,它将被转换为 XML 格式:

@Root(name = "restrict")
public class Restrict {@Attribute(name = "Type")private int type;// Constructorpublic Restrict(int type) {this.type = type;}// Getter and Setterpublic int getType() {return type;}public void setType(int type) {this.type = type;}
}

3. 创建 API 接口

定义一个接口来描述你的 API 端点:

public interface ApiService {@Headers({"Content-Type: application/xml",})@POST("xxxx")Call<Void> sendRestrict(@Body Restrict restrict);
}

4. 配置 Retrofit 实例

配置 Retrofit 实例并创建 API 服务:

public class RetrofitClient {private static final String BASE_URL = "xxxxxxxxx";private static Retrofit retrofit = null;public static Retrofit getClient() {if (retrofit == null) {retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(SimpleXmlConverterFactory.create()).build();}return retrofit;}public static ApiService getApiService() {return getClient().create(ApiService.class);}
}

5. 发起请求

最后,使用创建的 ApiService 发起请求:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ApiService apiService = RetrofitClient.getApiService();String xmlData = "";MediaType xmlMediaType = MediaType.parse("application/xml");RequestBody xmlBody = RequestBody.create(xmlData, xmlMediaType);Call<Void> call = apiService.sendRestrict(xmlBody);call.enqueue(new Callback<Void>() {@Overridepublic void onResponse(Call<Void> call, Response<Void> response) {if (response.isSuccessful()) {Log.d("MainActivity", "Request successful");} else {Log.e("MainActivity", "Request failed");}}@Overridepublic void onFailure(Call<Void> call, Throwable t) {Log.e("MainActivity", "Error: " + t.getMessage());}});}
}

XML请求能力主要就两点:

1、添加内置的 simplexml 依赖,添加Retrofit转换器  .addConverterFactory(SimpleXmlConverterFactory.create())

2、使用 MediaType.parse 方法定义请求体的媒体类型为 application/xml

比较简单,但是我还是在这个功能上耗费了两个小时时间差点翻车,主要是几个同事需要马上使用。按照步骤死活无法成功,

我使用的方式是 bean转 xml 请求。

        String xml = "<xxx></xxx>";Serializer serializer = new Persister();Restrict restrict = serializer.read(Restrict.class, xml);

我甚至怀疑接口是错误的,都没有怀疑这种方式有问题,用终端跑一下,成功返回数据。

然后怀疑参数问题,怀疑网络问题都没有怀疑这样的写法有什么问题。最后没办法给Okhttp添加了拦截器打印请求参数,发现 为啥是 json形式请求?说实在的至今没搞清楚为什么~

           String xmlData = "";MediaType xmlMediaType = MediaType.parse("application/xml");RequestBody xmlBody = RequestBody.create(xmlData, xmlMediaType);
        if (request.body() != null && request.body().contentType() != null) {MediaType contentType = request.body().contentType();if (contentType.subtype().equals("xml") || contentType.subtype().equals("json")) {Buffer buffer = new Buffer();request.body().writeTo(buffer);Log.e(TAG,"Request body (" + contentType + "): " + buffer.readUtf8());}}


文章转载自:

http://zg2s6EHN.nLysd.cn
http://FX4ilzGu.nLysd.cn
http://rJUuQCbO.nLysd.cn
http://dyxvlOtD.nLysd.cn
http://6f9eMAGI.nLysd.cn
http://tTp40g8n.nLysd.cn
http://6TqORIta.nLysd.cn
http://X1CIkKe8.nLysd.cn
http://Mb6xQVy7.nLysd.cn
http://q5Rw7dhC.nLysd.cn
http://uLW7HcOV.nLysd.cn
http://M0oNSkkz.nLysd.cn
http://ZYx7WrtR.nLysd.cn
http://knEDeULf.nLysd.cn
http://JcjG06Q2.nLysd.cn
http://AMQAzsJo.nLysd.cn
http://UuYpJMQB.nLysd.cn
http://y8Sn4O2W.nLysd.cn
http://aLMb13oz.nLysd.cn
http://x718Epi7.nLysd.cn
http://cLSuRJax.nLysd.cn
http://GxYsUqrD.nLysd.cn
http://sTJpdB0v.nLysd.cn
http://itrUJ16S.nLysd.cn
http://0aEpt4aL.nLysd.cn
http://S7rniIbo.nLysd.cn
http://jZO0ck7R.nLysd.cn
http://tj7Wtuts.nLysd.cn
http://FlNQ75gy.nLysd.cn
http://4pHc4Hmx.nLysd.cn
http://www.dtcms.com/wzjs/763974.html

相关文章:

  • 手机网站开发哪家好今天河南重大新闻
  • 网站建设期间注意事项深圳市外贸公司
  • 智能科技网站模板下载地址网页设计代码全过程
  • 营销型网站需要注意广东网站se0优化公司
  • 模板网站大全百度网盘app下载安装手机版
  • 旅游网站策划wordpress提醒用法
  • 做自媒体好还是网站好学网站开发多久
  • 网站报价单模板网页设计的版式有哪些
  • 广州网站制作哪里好html5做网站优势
  • 中国手表网站祁阳做网站
  • python爬虫做网站郑州网站制作招聘
  • 网站关键词优化外包服务江北区网络推广技巧
  • 云服务器 多个网站如何建立一个大型的网站
  • 用wordpress做购物网站公司大全免费查询
  • 做淘客网站要多大的服务器wordpress 按点击排序
  • 网站案例英文营销网站中最重要的部分是
  • 网站背景图片素材 唯美网页设计模板免费下载网站
  • 给人做网站赚钱吗h5网页制作模板
  • python购物网站开发流程图下载了字体如何安装在wordpress
  • 东莞金融网站建设html静态网站模板
  • 大名网站建设莱芜信誉好的网络推广公司
  • 汕头老城图片怀化网站优化
  • 做个网站需要多久网站设计费用多少山西seo关键词优化软件搜索
  • 完成职教集团网站建设华讯网络工程师待遇
  • wordpress grace 下载浙江seo博客
  • 网站icp备案查询截图重庆企业seo网络推广外包
  • 上传文档网站开发建设运营平台网站的方法
  • 1920的网站做字体大小企业网站维护怎么做
  • 重庆大良网站建设用ps制作海报教程方法步骤
  • 房屋网在线seo