前言:
各位同学大家好,有段时间没有给大家更新文章 ,最近还在学习鸿蒙开发的支持,就想着把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布局代码
- <?xmlversion="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 类封装
- packagecom.example.hmsrxjava_demo.net;
- importjava.io.IOException;
- importio.reactivex.rxjava3.annotations.NonNull;
- importohos.agp.render.render3d.BuildConfig;
- importokhttp3.Interceptor;
- importokhttp3.OkHttpClient;
- importokhttp3.Request;
- importokhttp3.Response;
- importokhttp3.logging.HttpLoggingInterceptor;
- importretrofit2.Retrofit;
- importretrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
- importretrofit2.converter.gson.GsonConverterFactory;
- /**
- *description:
- */
- publicclassRetrofitClient{
- privatestaticvolatileRetrofitClientinstance;
- privateAPIServiceapiService;
- privateStringbaseUrl="https://www.wanandroid.com";
- privateRetrofitretrofit;
- privateOkHttpClientokHttpClient;
- privateRetrofitClient(){
- }
- publicstaticRetrofitClientgetInstance(){
- if(instance==null){
- synchronized(RetrofitClient.class){
- if(instance==null){
- instance=newRetrofitClient();
- }
- }
- }
- returninstance;
- }
- /**
- *设置Header
- *
- *@return
- */
- privateInterceptorgetHeaderInterceptor(){
- returnnewInterceptor(){
- @Override
- publicResponseintercept(@NonNullChainchain)throwsIOException{
- Requestoriginal=chain.request();
- Request.BuilderrequestBuilder=original.newBuilder();
- //添加Token如果需要添加请求头可以统一在这里添加
- //Request.BuilderrequestBuilder=original.newBuilder().header("token","");
- Requestrequest=requestBuilder.build();
- returnchain.proceed(request);
- }
- };
- }
- /**
- *设置拦截器打印日志
- *
- *@return
- */
- privateInterceptorgetInterceptor(){
- HttpLoggingInterceptorinterceptor=newHttpLoggingInterceptor();
- //显示日志
- interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
- returninterceptor;
- }
- publicOkHttpClientgetOkHttpClient(){
- if(okHttpClient==null){
- //如果为DEBUG就打印日志
- if(BuildConfig.DEBUG){
- okHttpClient=newOkHttpClient().newBuilder()
- //设置Header
- .addInterceptor(getHeaderInterceptor())
- //设置拦截器
- .addInterceptor(getInterceptor())
- .build();
- }else{
- okHttpClient=newOkHttpClient().newBuilder()
- //设置Header
- .addInterceptor(getHeaderInterceptor())
- .build();
- }
- }
- returnokHttpClient;
- }
- publicAPIServicegetApi(){
- //初始化一个client,不然retrofit会自己默认添加一个
- if(retrofit==null){
- retrofit=newRetrofit.Builder()
- //设置网络请求的Url地址
- .baseUrl(baseUrl)
- //设置数据解析器
- .addConverterFactory(GsonConverterFactory.create())
- //设置网络请求适配器,使其支持RxJava与RxAndroid
- .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
- .client(getOkHttpClient())
- .build();
- }
- //创建——网络请求接口——实例
- if(apiService==null){
- apiService=retrofit.create(APIService.class);
- }
- returnapiService;
- }
- }
我们写了一个单例来获取 RetrofitClient 实力并且设置的了请求头 handler 和设置OKHTTP 日志拦截器
然后定义了 getApi 方法来获取 APIService 的实例
- RxScheduler
RXjava 线程调度
- packagecom.example.hmsrxjava_demo.net;
- importcom.example.hmsrxjava_demo.HarmonySchedulers;
- importorg.reactivestreams.Publisher;
- importio.reactivex.rxjava3.core.Flowable;
- importio.reactivex.rxjava3.core.FlowableTransformer;
- importio.reactivex.rxjava3.core.Observable;
- importio.reactivex.rxjava3.core.ObservableSource;
- importio.reactivex.rxjava3.core.ObservableTransformer;
- importio.reactivex.rxjava3.schedulers.Schedulers;
- /**
- *description:RXjava线程调度
- */
- publicclassRxScheduler{
- /**
- *统一线程处理
- *
- *@param<T>指定的泛型类型
- *@returnFlowableTransformer
- */
- publicstatic<T>FlowableTransformer<T,T>Flo_io_main(){
- returnnewFlowableTransformer<T,T>(){
- @Override
- publicPublisher<T>apply(Flowable<T>upstream){
- returnupstream.subscribeOn(Schedulers.io())
- .observeOn(HarmonySchedulers.mainThread());
- }
- };
- }
- /**
- *统一线程处理
- *
- *@param<T>指定的泛型类型
- *@returnObservableTransformer*/
- publicstatic<T>ObservableTransformer<T,T>Obs_io_main(){
- returnnewObservableTransformer<T,T>(){
- @Override
- publicObservableSource<T>apply(Observable<T>upstream){
- returnupstream.subscribeOn(Schedulers.io())
- .observeOn(HarmonySchedulers.mainThread());
- }
- };
- }
- }
这里代码就参考了 安卓里面 部分没有的 HarmonySchedulers.mainThread() 参考了安卓里面的自己实现了一下
- APIService
处理网络请求的接口 类 所有网络请求的都写在 APIService 写法和安卓的 Retrofitle类似
- packagecom.example.hmsrxjava_demo.net;
- importcom.example.hmsrxjava_demo.bean.BaseObjectBean;
- importcom.example.hmsrxjava_demo.bean.LoginBean;
- importio.reactivex.rxjava3.core.Observable;
- importretrofit2.http.Field;
- importretrofit2.http.FormUrlEncoded;
- importretrofit2.http.POST;
- /**
- *Description:
- */
- publicinterfaceAPIService{
- /**
- *登陆
- *
- *@paramusername账号
- *@parampassword密码
- *@return
- */
- @FormUrlEncoded
- @POST("user/login")
- Observable<BaseObjectBean<LoginBean>>login(@Field("username")Stringusername,
- @Field("password")Stringpassword);
- }
base类
- BaseAbility
- packagecom.example.hmsrxjava_demo.base;
- importohos.aafwk.ability.Ability;
- importohos.aafwk.content.Intent;
- publicabstractclassBaseAbilityextendsAbility{
- @Override
- protectedvoidonStart(Intentintent){
- super.onStart(intent);
- super.setUIContent(getLayoutId());
- initView();
- }
- @Override
- protectedvoidonStop(){
- super.onStop();
- }
- /**
- *设置布局
- *
- *@return
- */
- publicabstractintgetLayoutId();
- /**
- *初始化视图
- */
- publicabstractvoidinitView();
- }
- BaseMvpAbility
- packagecom.example.hmsrxjava_demo.base;
- importohos.aafwk.content.Intent;
- publicabstractclassBaseMvpAbility<TextendsBasePresenter>extendsBaseAbilityimplementsBaseView{
- protectedTmPresenter;
- @Override
- protectedvoidonStart(Intentintent){
- super.onStart(intent);
- }
- @Override
- protectedvoidonStop(){
- if(mPresenter!=null){
- mPresenter.detachView();
- }
- super.onStop();
- }
- }
- BasePresenter
- packagecom.example.hmsrxjava_demo.base;
- /**
- *Description:
- */
- publicclassBasePresenter<VextendsBaseView>{
- protectedVmView;
- /**
- *绑定view,一般在初始化中调用该方法
- *
- *@paramviewview
- */
- publicvoidattachView(Vview){
- this.mView=view;
- }
- /**
- *解除绑定view,一般在onDestroy中调用
- */
- publicvoiddetachView(){
- this.mView=null;
- }
- /**
- *View是否绑定
- *
- *@return
- */
- publicbooleanisViewAttached(){
- returnmView!=null;
- }
- }
-
BaseView
- packagecom.example.hmsrxjava_demo.base;
- /**
- *Description:
- */
- publicinterfaceBaseView{
- /**
- *显示加载中
- */
- voidshowLoading();
- /**
- *隐藏加载
- */
- voidhideLoading();
- /**
- *数据获取失败
- *@paramerrMessage
- */
- voidonError(StringerrMessage);
- }
- Model 层
- packagecom.example.hmsrxjava_demo.contract;
- importcom.example.hmsrxjava_demo.base.BaseView;
- importcom.example.hmsrxjava_demo.bean.BaseObjectBean;
- importcom.example.hmsrxjava_demo.bean.LoginBean;
- importio.reactivex.rxjava3.core.Observable;
- /**
- *Description:
- */
- publicinterfaceMainContract{
- interfaceModel{
- Observable<BaseObjectBean<LoginBean>>login(Stringusername,Stringpassword);
- }
- interfaceViewextendsBaseView{
- @Override
- voidshowLoading();
- @Override
- voidhideLoading();
- @Override
- voidonError(StringerrMessage);
- voidonSuccess(BaseObjectBean<LoginBean>bean);
- }
- interfacePresenter{
- /**
- *登陆
- *
- *@paramusername
- *@parampassword
- */
- voidlogin(Stringusername,Stringpassword);
- }
- }
- ##model 实现层
- packagecom.example.hmsrxjava_demo.model;
- importcom.example.hmsrxjava_demo.bean.BaseObjectBean;
- importcom.example.hmsrxjava_demo.bean.LoginBean;
- importcom.example.hmsrxjava_demo.contract.MainContract;
- importcom.example.hmsrxjava_demo.net.RetrofitClient;
- importio.reactivex.rxjava3.core.Observable;
- /**
- *Description:
- */
- publicclassMainModelimplementsMainContract.Model{
- privatestaticfinalStringTAG="MainModel";
- @Override
- publicObservable<BaseObjectBean<LoginBean>>login(Stringusername,Stringpassword){
- System.out.println("MainModellogin被调用");
- returnRetrofitClient.getInstance().getApi().login(username,password);
- }
- }
-
Presenter层
- packagecom.example.hmsrxjava_demo.presenter;
- importcom.example.hmsrxjava_demo.base.BasePresenter;
- importcom.example.hmsrxjava_demo.bean.BaseObjectBean;
- importcom.example.hmsrxjava_demo.bean.LoginBean;
- importcom.example.hmsrxjava_demo.contract.MainContract;
- importcom.example.hmsrxjava_demo.model.MainModel;
- importcom.example.hmsrxjava_demo.net.RxScheduler;
- importio.reactivex.rxjava3.annotations.NonNull;
- importio.reactivex.rxjava3.core.Observer;
- importio.reactivex.rxjava3.disposables.Disposable;
- /**
- *Description:
- */
- publicclassMainPresenterextendsBasePresenter<MainContract.View>implementsMainContract.Presenter{
- privateMainContract.Modelmodel;
- publicMainPresenter(){
- model=newMainModel();
- }
- @Override
- publicvoidlogin(Stringusername,Stringpassword){
- //View是否绑定如果没有绑定,就不执行网络请求
- if(!isViewAttached()){
- return;
- }
- model.login(username,password)
- .compose(RxScheduler.Obs_io_main())
- .subscribe(newObserver<BaseObjectBean<LoginBean>>(){
- @Override
- publicvoidonSubscribe(@NonNullDisposabled){
- mView.showLoading();
- }
- @Override
- publicvoidonNext(@NonNullBaseObjectBean<LoginBean>loginBeanBaseObjectBean){
- mView.onSuccess(loginBeanBaseObjectBean);
- System.out.println("onNext—–>");
- }
- @Override
- publicvoidonError(@NonNullThrowablee){
- mView.onError(e.getMessage());
- mView.hideLoading();
- }
- @Override
- publicvoidonComplete(){
- mView.hideLoading();
- }
- });
- }
- }
-
MainAbility 中 具体调用
- packagecom.example.hmsrxjava_demo;
- importcom.example.hmsrxjava_demo.base.BaseMvpAbility;
- importcom.example.hmsrxjava_demo.bean.BaseObjectBean;
- importcom.example.hmsrxjava_demo.bean.LoginBean;
- importcom.example.hmsrxjava_demo.contract.MainContract;
- importcom.example.hmsrxjava_demo.presenter.MainPresenter;
- importohos.agp.components.Button;
- importohos.agp.components.Component;
- importohos.agp.components.TextField;
- importohos.agp.window.dialog.ToastDialog;
- publicclassMainAbilityextendsBaseMvpAbility<MainPresenter>implementsMainContract.View{
- privateTextFieldtextUsername,textpasswrod;
- privateStringusername,password;
- privateButtonloginBtn;
- privateMainPresenterpresenter;
- @Override
- publicintgetLayoutId(){
- returnResourceTable.Layout_ability_main;
- }
- @Override
- publicvoidinitView(){
- textUsername=(TextField)findComponentById(ResourceTable.Id_text_username);
- textpasswrod=(TextField)findComponentById(ResourceTable.Id_text_password);
- presenter=newMainPresenter();
- presenter.attachView(this);
- loginBtn=(Button)findComponentById(ResourceTable.Id_login_btn);
- if(loginBtn!=null){
- loginBtn.setClickedListener(newComponent.ClickedListener(){
- @Override
- publicvoidonClick(Componentcomponent){
- System.out.println("点击登录按钮");
- username=textUsername.getText();
- password=textpasswrod.getText();
- if(username!=null&&password!=null){
- presenter.login(username,password);
- //login(username,password);
- }else{
- newToastDialog(MainAbility.this).setText("账号密码不输不能为空").show();}
- }
- });
- }
- }
- @Override
- publicvoidonSuccess(BaseObjectBean<LoginBean>bean){
- System.out.println(bean.getErrorCode()+bean.getErrorMsg());
- newToastDialog(MainAbility.this).setText(bean.getErrorCode()+bean.getErrorMsg()).show();
- }
- @Override
- publicvoidshowLoading(){
- }
- @Override
- publicvoidhideLoading(){
- }
- @Override
- publicvoidonError(StringerrMessage){
- }
- }
到此 鸿蒙 MVP+ Rxjava+Retrofit+okhttp 实现教程 使用起来和安卓的用法非常像 我这里很多代码是复制过来 同学们可以下载完整的代码来尝试。
最后总结:
鸿蒙中MVP+ Rxjava+Retrofit+okhttp 和安卓里面基本如出一辙 只是很少地方有些诧异,同学们如果不是很熟悉 Rxjava+Retrofit+okhttp 请先去看看官方教程 还有mvp模式的不熟悉的请切翻阅我之前的文章 。
原文链接:https://harmonyos.51cto.com