您现在的位置是:亿华云 > 系统运维
鸿蒙 MVP+ Rxjava+Retrofit+okhttp 实现教程
亿华云2025-10-02 21:07:38【系统运维】5人已围观
简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com前言:各位同学大家好,有段时间没有给大家更新文章 ,最近还在学习鸿蒙开发的支持,就想着把a
想了解更多内容,鸿蒙请访问:
和华为官方合作共建的现教鸿蒙技术社区
https://harmonyos.51cto.com
前言:
各位同学大家好,有段时间没有给大家更新文章 ,鸿蒙最近还在学习鸿蒙开发的现教支持,就想着把android里面部分用到知识搬到鸿蒙里面 因为基础语言都是鸿蒙java 语言,所以就写了现在这教程 那么废话不多说我们正式开始
##效果图

准备工作
1 安装鸿蒙开发环境 大家可以看我之前的现教文章
需要用到的三方库
//okhttp3 implementation com.squareup.okhttp3:okhttp:4.2.0 implementation "com.squareup.okhttp3:logging-interceptor:3.10.0" //retrofit2 implementation com.squareup.retrofit2:retrofit:2.9.0 implementation com.squareup.retrofit2:converter-gson:2.9.0 implementation com.squareup.retrofit2:adapter-rxjava3:2.9.0请在build.gradle里面添加依赖然后sygn now 同步下载依赖
具体实现
MainAbility布局代码
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:orientation="vertical"> <Text ohos:id="$+id:text_fruit_tag" ohos:height="35vp" ohos:width="match_parent" ohos:background_element="$graphic:text_element" ohos:layout_alignment="left" ohos:text="账户" ohos:text_size="85" ohos:right_margin="20vp" ohos:left_margin="20vp" ohos:top_margin="25vp" ohos:text_color="#000000" /> <TextField ohos:id="$+id:text_username" ohos:height="35vp" ohos:width="match_parent" ohos:background_element="$graphic:text_element" ohos:layout_alignment="left" ohos:text_size="50" ohos:right_margin="20vp" ohos:left_margin="20vp" ohos:text_color="#000000" ohos:top_margin="25vp" ohos:basement="#000099" ohos:hint="请输入账号" /> <Text ohos:id="$+id:text_number_tag" ohos:height="35vp" ohos:width="match_parent" ohos:background_element="$graphic:text_element" ohos:layout_alignment="left" ohos:text="密码" ohos:text_size="85" ohos:right_margin="20vp" ohos:left_margin="20vp" ohos:text_color="#000000" ohos:top_margin="25vp" /> <TextField ohos:id="$+id:text_password" ohos:height="35vp" ohos:width="match_parent" ohos:background_element="$graphic:text_element" ohos:layout_alignment="left" ohos:text_size="50" ohos:right_margin="20vp" ohos:left_margin="20vp" ohos:text_color="#000000" ohos:top_margin="25vp" ohos:basement="#000099" ohos:hint="请输入密码" /> <Button ohos:id="$+id:login_btn" ohos:width="match_parent" ohos:height="50vp" ohos:text="登录" ohos:background_element="$graphic:button_element" ohos:text_size="50" ohos:text_color="#FFFFFF" ohos:top_margin="25vp" ohos:right_margin="20vp" ohos:left_margin="20vp" /> </DirectionalLayout>布局效果

我们的目的很明确 我们想拿到2个输入框的内容然后调用网络接口来实现登录的操作 业务非常简单
但是今天要用 MVP+ Rxjava+Retrofit+okhttp 来实现
网络核心部分
RetrofitClient 类封装 package com.example.hmsrxjava_demo.net; import java.io.IOException; import io.reactivex.rxjava3.annotations.NonNull; import ohos.agp.render.render3d.BuildConfig; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; /** * description: */ public class RetrofitClient { private static volatile RetrofitClient instance; private APIService apiService; private String baseUrl = "https://www.wanandroid.com"; private Retrofit retrofit; private OkHttpClient okHttpClient; private RetrofitClient() { } public static RetrofitClient getInstance() { if (instance == null) { synchronized (RetrofitClient.class) { if (instance == null) { instance = new RetrofitClient(); } } } return instance; } /** * 设置Header * * @return */ private Interceptor getHeaderInterceptor() { return new Interceptor() { @Override public Response intercept(@NonNull Chain chain) throws IOException { Request original = chain.request(); Request.Builder requestBuilder = original.newBuilder(); //添加Token 如果需要添加请求头可以统一在这里添加 // Request.Builder requestBuilder = original.newBuilder().header("token", ""); Request request = requestBuilder.build(); return chain.proceed(request); } }; } /** * 设置拦截器 打印日志 * * @return */ private Interceptor getInterceptor() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); //显示日志 interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); return interceptor; } public OkHttpClient getOkHttpClient() { if (okHttpClient == null) { //如果为DEBUG 就打印日志 if (BuildConfig.DEBUG) { okHttpClient = new OkHttpClient().newBuilder() //设置Header .addInterceptor(getHeaderInterceptor()) //设置拦截器 .addInterceptor(getInterceptor()) .build(); } else { okHttpClient = new OkHttpClient().newBuilder() //设置Header .addInterceptor(getHeaderInterceptor()) .build(); } } return okHttpClient; } public APIService getApi() { //初始化一个client,不然retrofit会自己默认添加一个 if (retrofit == null) { retrofit = new Retrofit.Builder() //设置网络请求的服务器托管Url地址 .baseUrl(baseUrl) //设置数据解析器 .addConverterFactory(GsonConverterFactory.create()) //设置网络请求适配器,使其支持RxJava与RxAndroid .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .client(getOkHttpClient()) .build(); } //创建—— 网络请求接口—— 实例 if (apiService==null){ apiService = retrofit.create(APIService.class); } return apiService; } }我们写了一个单例来获取 RetrofitClient 实力并且设置的鸿蒙了请求头 handler 和设置OKHTTP 日志拦截器
然后定义了 getApi 方法来获取 APIService 的实例
RxSchedulerRXjava 线程调度
package com.example.hmsrxjava_demo.net; import com.example.hmsrxjava_demo.HarmonySchedulers; import org.reactivestreams.Publisher; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.FlowableTransformer; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.ObservableSource; import io.reactivex.rxjava3.core.ObservableTransformer; import io.reactivex.rxjava3.schedulers.Schedulers; /** * description:RXjava 线程调度 */ public class RxScheduler { /** * 统一线程处理 * * @param <T> 指定的泛型类型 * @return FlowableTransformer */ public static <T> FlowableTransformer< T, T> Flo_io_main() { return new FlowableTransformer<T, T>() { @Override public Publisher<T> apply(Flowable<T> upstream) { return upstream.subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()); } }; } /* * * 统一线程处理 * * @param <T> 指定的泛型类型 * @return ObservableTransformer*/ public static <T> ObservableTransformer<T, T> Obs_io_main() { return new ObservableTransformer<T, T>() { @Override public ObservableSource<T> apply( Observable<T> upstream) { return upstream.subscribeOn(Schedulers.io()) .observeOn(HarmonySchedulers.mainThread()); } }; } }这里代码就参考了 安卓里面 部分没有的 HarmonySchedulers.mainThread() 参考了安卓里面的自己实现了一下
APIService处理网络请求的接口 类 所有网络请求的都写在 APIService 写法和安卓的 Retrofitle类似
package com.example.hmsrxjava_demo.net; import com.example.hmsrxjava_demo.bean.BaseObjectBean; import com.example.hmsrxjava_demo.bean.LoginBean; import io.reactivex.rxjava3.core.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; /** * Description: */ public interface APIService { /** * 登陆 * * @param username 账号 * @param password 密码 * @return */ @FormUrlEncoded @POST("user/login") Observable<BaseObjectBean<LoginBean>> login(@Field("username") String username, @Field("password") String password); }base类
BaseAbility package com.example.hmsrxjava_demo.base; import ohos.aafwk.ability.Ability; import ohos.aafwk.content.Intent; public abstract class BaseAbility extends Ability { @Override protected void onStart(Intent intent) { super.onStart(intent); super.setUIContent(getLayoutId()); initView(); } @Override protected void onStop() { super.onStop(); } /** * 设置布局 * * @return */ public abstract int getLayoutId(); /** * 初始化视图 */ public abstract void initView(); } BaseMvpAbility package com.example.hmsrxjava_demo.base; import ohos.aafwk.content.Intent; public abstract class BaseMvpAbility <T extends BasePresenter>extends BaseAbility implements BaseView { protected T mPresenter; @Override protected void onStart(Intent intent) { super.onStart(intent); } @Override protected void onStop() { if (mPresenter != null) { mPresenter.detachView(); } super.onStop(); } } BasePresenter package com.example.hmsrxjava_demo.base; /** * Description: */ public class BasePresenter<V extends BaseView> { protected V mView; /** * 绑定view,一般在初始化中调用该方法 * * @param view view */ public void attachView(V view) { this.mView = view; } /** * 解除绑定view,现教一般在onDestroy中调用 */ public void detachView() { this.mView = null; } /** * View是鸿蒙否绑定 * * @return */ public boolean isViewAttached() { return mView != null; } }BaseView
package com.example.hmsrxjava_demo.base; /** * Description: */ public interface BaseView { /** * 显示加载中 */ void showLoading(); /** * 隐藏加载 */ void hideLoading(); /** * 数据获取失败 * @param errMessage */ void onError(String errMessage); } Model 层 package com.example.hmsrxjava_demo.contract; import com.example.hmsrxjava_demo.base.BaseView; import com.example.hmsrxjava_demo.bean.BaseObjectBean; import com.example.hmsrxjava_demo.bean.LoginBean; import io.reactivex.rxjava3.core.Observable; /** * Description: */ public interface MainContract { interface Model { Observable<BaseObjectBean<LoginBean>> login(String username, String password); } interface View extends BaseView { @Override void showLoading(); @Override void hideLoading(); @Override void onError(String errMessage); void onSuccess(BaseObjectBean<LoginBean> bean); } interface Presenter { /** * 登陆 * * @param username * @param password */ void login(String username, String password); } } ##model 实现层 package com.example.hmsrxjava_demo.model; import com.example.hmsrxjava_demo.bean.BaseObjectBean; import com.example.hmsrxjava_demo.bean.LoginBean; import com.example.hmsrxjava_demo.contract.MainContract; import com.example.hmsrxjava_demo.net.RetrofitClient; import io.reactivex.rxjava3.core.Observable; /** * Description: */ public class MainModel implements MainContract.Model { private static final String TAG = "MainModel"; @Override public Observable<BaseObjectBean<LoginBean>> login(String username, String password) { System.out.println("MainModel login 被调用"); return RetrofitClient.getInstance().getApi().login(username,password); } }Presenter层
package com.example.hmsrxjava_demo.presenter; import com.example.hmsrxjava_demo.base.BasePresenter; import com.example.hmsrxjava_demo.bean.BaseObjectBean; import com.example.hmsrxjava_demo.bean.LoginBean; import com.example.hmsrxjava_demo.contract.MainContract; import com.example.hmsrxjava_demo.model.MainModel; import com.example.hmsrxjava_demo.net.RxScheduler; import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; /** * Description: */ public class MainPresenter extends BasePresenter<MainContract.View> implements MainContract.Presenter { private MainContract.Model model; public MainPresenter() { model = new MainModel(); } @Override public void login(String username, String password) { //View是否绑定 如果没有绑定,亿华云就不执行网络请求 if (!isViewAttached()) { return; } model.login(username,现教 password) .compose(RxScheduler.Obs_io_main()) .subscribe(new Observer<BaseObjectBean<LoginBean>>() { @Override public void onSubscribe(@NonNull Disposable d) { mView.showLoading(); } @Override public void onNext(@NonNull BaseObjectBean<LoginBean> loginBeanBaseObjectBean) { mView.onSuccess(loginBeanBaseObjectBean); System.out.println("onNext ----- >"); } @Override public void onError(@NonNull Throwable e) { mView.onError(e.getMessage()); mView.hideLoading(); } @Override public void onComplete() { mView.hideLoading(); } }); } }MainAbility 中 具体调用
package com.example.hmsrxjava_demo; import com.example.hmsrxjava_demo.base.BaseMvpAbility; import com.example.hmsrxjava_demo.bean.BaseObjectBean; import com.example.hmsrxjava_demo.bean.LoginBean; import com.example.hmsrxjava_demo.contract.MainContract; import com.example.hmsrxjava_demo.presenter.MainPresenter; import ohos.agp.components.Button; import ohos.agp.components.Component; import ohos.agp.components.TextField; import ohos.agp.window.dialog.ToastDialog; public class MainAbility extends BaseMvpAbility<MainPresenter>implements MainContract.View { private TextField textUsername, textpasswrod; private String username, password; private Button loginBtn; private MainPresenter presenter; @Override public int getLayoutId() { return ResourceTable.Layout_ability_main; } @Override public void initView() { textUsername= (TextField) findComponentById(ResourceTable.Id_text_username); textpasswrod= (TextField) findComponentById(ResourceTable.Id_text_password); presenter=new MainPresenter(); presenter.attachView(this); loginBtn= (Button) findComponentById(ResourceTable.Id_login_btn); if(loginBtn!=null){ loginBtn.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { System.out.println("点击登录按钮"); username=textUsername.getText(); password=textpasswrod.getText(); if(username!=null&&password!=null){ presenter.login(username,password); // login(username,password); }else { new ToastDialog(MainAbility.this).setText("账号密码不输不能为空").show(); } } }); } } @Override public void onSuccess(BaseObjectBean<LoginBean> bean) { System.out.println(bean.getErrorCode()+bean.getErrorMsg()); new ToastDialog(MainAbility.this).setText(bean.getErrorCode()+bean.getErrorMsg()).show(); } @Override public void showLoading() { } @Override public void hideLoading() { } @Override public void onError(String errMessage) { } }到此 鸿蒙 MVP+ Rxjava+Retrofit+okhttp 实现教程 使用起来和安卓的用法非常像 我这里很多代码是复制过来 同学们可以下载完整的代码来尝试。
最后总结:
鸿蒙中MVP+ Rxjava+Retrofit+okhttp 和安卓里面基本如出一辙 只是鸿蒙很少地方有些诧异,同学们如果不是现教很熟悉 Rxjava+Retrofit+okhttp 请先去看看官方教程 还有mvp模式的不熟悉的请切翻阅我之前的文章 。
想了解更多内容,鸿蒙请访问:
和华为官方合作共建的现教鸿蒙技术社区
https://harmonyos.51cto.com
很赞哦!(68695)