Kotlin 封装Rxjava,Retrofit网络请求,mvp实现登录页面

   本文主要是简单的使用并且封装了Rxjava和Retrofit实现网络请求,mvp实现登录的操作,主要实现语言是Kotlin
    **1添加依赖,本文是基于2.0版本的**
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

2 封装Retrofit管理类,并且获取网络请求接口的实例

class UserRetrofitManager private constructor() {
    //管理网络请求接口的类
    lateinit var userApiStore: UserApiStore

    //静态内部类实现单例模式
    companion object {
        val instance = RetrofitHolder.holder
    }

    private object RetrofitHolder {
        val holder = UserRetrofitManager()
    }
    //初始化 配置一些网络请求参数,以及在调试环境下打印日志
    //创建retrofit实例,获取UserApiStore
    fun init() {
        var loggingInterceptor: HttpLoggingInterceptor =
            HttpLoggingInterceptor(HttpLoggingInterceptor.Logger {
                if (BeautyUser.isDebugModel) {
                    BLog.i("retrofit", it)
                }
            })
        val mOkHttpClient = OkHttpClient.Builder()
            .connectTimeout(10000, TimeUnit.MILLISECONDS)
            .writeTimeout(10000, TimeUnit.MILLISECONDS)//写入超时10秒
            .readTimeout(10000, TimeUnit.MILLISECONDS)
            .addInterceptor(loggingInterceptor)
            .build();

        var retrofit: Retrofit = Retrofit.Builder()
            .client(mOkHttpClient)
            .baseUrl("http://tw.adnonstop.com/")//只是使用了一个baseusrl
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(Gson()))
            .build();
        userApiStore = retrofit.create(UserApiStore::class.java)
    }
}

在application中初始化

class UserApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        BeautyMallConfig.mApplication = this
        UserRetrofitManager.instance.init()
    }
}

网络请求接口配置

interface UserApiStore {
   //返回值为Observable
    @POST("modules/apps/task_platform/api/v1/member_check_account_pwd_api.php")
    fun getObservable(@Body requestBody: RequestBody): Observable<LoginBeanResult>

    //返回值为Call
    @POST("modules/apps/task_platform/api/v1/member_check_account_pwd_api.php")
    fun getCall(@Body requestBody: RequestBody): Call<LoginBeanResult>
}

封装请求过程以及返回的数据结果

class ApiRxResponse {
    //网络请求过程,传入构建的observable以及网络请求返回的实体类 T
    //处理数据返回结果接口 NetWorkCallBack 对应的是成功,失败,无网络等情况分别进行处理
    fun <T> doCall(observable: Observable<T>, netWorkCallBack: NetWorkCallBack<T>) {
        if (NetWorkUtils.isNetworkAvailable(BeautyMallConfig.mApplication)) {
            observable.subscribeOn(Schedulers.io())         //在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果
                .subscribe(object : Observer<T> {
                    override fun onComplete() {
                        netWorkCallBack.onComplete()
                    }

                    override fun onSubscribe(d: Disposable) {
                        netWorkCallBack.onSubscribe()

                    }

                    override fun onNext(t: T) {
                        netWorkCallBack.onSuccess(t)
                    }

                    override fun onError(e: Throwable) {
                        netWorkCallBack.onError(e)
                        if (e is HttpException) {
                            BLog.i("login    observable error code :   " + e.code())
                        }
                    }

                })
        } else {
            netWorkCallBack.onNetError()
        }
    }
}

 interface NetWorkCallBack<T> {
        fun onSuccess(t: T)
        fun onError(throwable: Throwable)
        fun onNetError()
        fun onSubscribe()
        fun onComplete()
    }

搭建mvp
MVP模式的整个核心流程:
View与Model并不直接交互,而是使用Presenter作为View与Model之间的桥梁。其中Presenter中同时持有View层的Interface的引用以及Model层的引用,而View层持有Presenter层引用。当View层某个界面需要展示某些数据的时候,首先会调用Presenter层的引用,然后Presenter层会调用Model层请求数据,当Model层数据加载成功之后会调用Presenter层的回调方法通知Presenter层数据加载情况,最后Presenter层再调用View层的接口将加载后的数据展示给用户。
在这里插入图片描述
每个页面都有不同的view以及presenter,所以我们把公共的部分抽取出来

加载数据之前的动画和加载后取消动画的接口
class BaseContract {
    interface BaseView {
        fun showLoading();
        fun hideLoading();
    }
}

presenter中的逻辑功能不同,但是会拥有view的引用

open class BasePresenter<T : BaseContract.BaseView> {
    lateinit var mView: T;
}

activity中会含有view以及presenter的引用

open class BaseActivity: AppCompatActivity() {
}
open class BaseMvpActivity<T : BasePresenter<*>> : BaseActivity(), BaseContract.BaseView {
    override fun showLoading() {
    }
    override fun hideLoading() {
    }
    override fun onError() {
    }
    lateinit var mPresenter: T;//使用泛型,不知道是什么presenter
}
//进行网络请求并且获取数据结果 我们需要presenter传入 mobile 和password 
//并且通过netWorkCallBack返回给presenter结果
class LoginModel {
    private val JSON_TYPE =
        MediaType.parse("application/json; charset=utf-8")

    fun getLoginUserId(
        mobile: String,
        passWord: String,
        netWorkCallBack: NetWorkCallBack<LoginBeanResult>
    ) {
        val jsonObject = JSONObject()
        try {
            jsonObject.put("mobile", mobile)
            jsonObject.put("password", passWord)
            jsonObject.put("sign", "12345")
        } catch (e: JSONException) {
            e.printStackTrace()
        }
        var requestBody: RequestBody = RequestBody.create(JSON_TYPE, jsonObject.toString())
        var observable = UserRetrofitManager.instance.userApiStore.getObservable(requestBody)
        var apiResponse2 = ApiRxResponse()
        apiResponse2.doCall(observable, object : NetWorkCallBack<LoginBeanResult> {
            override fun onSuccess(t: LoginBeanResult) {
                netWorkCallBack.onSuccess(t)
            }

            override fun onError(throwable: Throwable) {
                netWorkCallBack.onError(throwable)
            }

            override fun onNetError() {
                netWorkCallBack.onNetError()
            }

            override fun onSubscribe() {
                netWorkCallBack.onSubscribe()
            }

            override fun onComplete() {
                netWorkCallBack.onComplete()
            }

        })
    }
}

实体类

public class LoginBeanResult {
    private int code;
    private String message;
    private DataBean data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public DataBean getData() {
        return data;
    }

    public void setData(DataBean data) {
        this.data = data;
    }

    @Keep
    public static class DataBean {
        private String user_id;

        public String getUser_id() {
            return user_id;
        }

        public void setUser_id(String user_id) {
            this.user_id = user_id;
        }

        @Override
        public String toString() {
            return "DataBean{" +
                    "user_id='" + user_id + '\'' +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "LoginBeanResult{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }
}

loginView 我们要添加一个方法

interface LoginView : BaseContract.BaseView {

    //通过错误码来提示用户错误信息
    fun errorCode(code: Int)
}

presenter 是view与model之间的桥梁,把model传回的数据结果在通过view的引用通知到activity

..mView 是BasePresenter 中的
class LoginPresenter : BasePresenter<LoginView>() {

    fun getUserId(mobile: String, passWord: String) {
        mView.showLoading()
        var loginModel: LoginModel = LoginModel()
        loginModel.getLoginUserId(mobile, passWord, object : NetWorkCallBack<LoginBeanResult> {
            override fun onSuccess(t: LoginBeanResult) {
                mView.hideLoading()
                //获取code
                mView.errorCode(Math.abs(t.code))
            }

            override fun onError(throwable: Throwable) {
                mView.hideLoading()
            }

            override fun onNetError() {
                mView.hideLoading()
            }

            override fun onSubscribe() {

            }

            override fun onComplete() {

            }

        })
    }
}

activity 中 实例化presenter和view 以及进行UI的操作

class LoginActivity : BaseMvpActivity<LoginPresenter>(), LoginView {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        //实例化presenter 和 view 
        mPresenter = LoginPresenter()
        mPresenter.mView = this;
        initListener();
    }

    private fun initListener() {
        btLogin.setOnClickListener(View.OnClickListener {
            mPresenter.getUserId(etPhoneNumber.text.toString(), etPassWord.text.toString())
        })
    }

    override fun errorCode(code: Int) {
        BLog.i("code :  $code")
    }

    override fun showLoading() {
        progressBar.visibility = View.VISIBLE
    }

    override fun hideLoading() {
        progressBar.visibility = View.GONE
    }
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.LoginActivity">

    <EditText
        android:id="@+id/etPhoneNumber"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:digits="1234567890"
        android:gravity="center"
        android:maxLength="11" />

    <EditText
        android:id="@+id/etPassWord"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:gravity="center"
        android:hint="输入密码"
        android:inputType="textPassword"
        android:maxLength="16" />

    <Button
        android:id="@+id/btLogin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:layout_marginTop="30dp"
        android:text="登录" />

    <Button
        android:id="@+id/btFinish"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="关闭" />

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" />

</LinearLayout>

部分相关的类

public class NetWorkUtils {
    private static final String TAG = NetWorkUtils.class.getSimpleName();
    //检测是否有网络

    public  static Boolean isNetworkAvailable(Context context){
        if (context != null) {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (connectivityManager != null) {
                NetworkInfo info = connectivityManager.getActiveNetworkInfo();
                if (info != null && info.isConnected()) {
                    //当前网络是连着的
                    if (info.getState() == NetworkInfo.State.CONNECTED || info.getState() == NetworkInfo.State.CONNECTING) {
                        //当前网络可用
                        return true;
                    }
                }
            }

        }
        return false;
    }
}

有什么问题欢迎留言!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值