本文主要是简单的使用并且封装了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;
}
}
有什么问题欢迎留言!!!