1. 程式人生 > >用Kotlin編寫Android:Retrofit+Rxjava嘗試

用Kotlin編寫Android:Retrofit+Rxjava嘗試

前言: 最近學習了安卓開發谷歌推薦的Kotlin語言,便用來嘗試了一下重構之前的MVP+Retrofit+Rxjava的程式碼,下面是我重構後的Kotlin程式碼

首先新增gradle的compile:

dependencies {
    compile 'io.reactivex.rxjava2:rxjava:2.0.7'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
    compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' compile 'com.squareup.okhttp3:okhttp:3.5.0' }

順便記錄一下最近Android Studio3.0的jar包問題:
在這裡插入圖片描述

解決方法:
    androidTestCompile('com.android.support:support-annotations:26.1.0'
) { force = true }

然後講一下Rxjava+retrofit開發:

步驟1: 建立 接收伺服器返回資料 的類
class BaseBean<T> {
    private var code: Int = 0//返回碼
    private var msg: String? = null//返回的資訊
    private var data: T? = null//返回的資料

    fun getCode(): Int {
        return code
    }
    /**
     * 判斷是否請求碼成功
     */
    fun
isSuccess(): Boolean { return this.code == GlobalContent.SUCCESS_CODE } fun getMsg(): String? { return msg } fun getData(): T? { return data } }
步驟2:建立 用於描述網路請求 的介面
interface LoginService {
    @FormUrlEncoded
    @POST("manager/login")
   fun submitLoginInfo(@Field("username") String username,@Field("password") String password):Observable<BaseBean<String>> ;
}
步驟3:建立Retrofit物件,建立 網路請求介面 的例項

在Model層建立

    /**
     * 建立Service
     */
    fun <T> createService(service: Class<T>): T? {

        checkService(service)

        return RetrofitFactory.getService(service)
    }
        /**
     * 檢驗引數Service
     * @param service
     * @param <T>
    </T> */
    private fun <T> checkService(service: Class<T>?) {
        if (service == null)
            throw NullPointerException("service must not be null!")
        if (!service.isInterface)
            throw IllegalArgumentException("Class must be interface !")
        if (service.interfaces.size > 0)
            throw IllegalArgumentException("service interfaces must not extends other interface!")

    }
    /**
     * 工廠設計模式:建立單例設計的Retrofit物件
     */
object RetrofitFactory {
    var mRetrofit: Retrofit? = null

    fun <T> getService(service: Class<T>): T? {
        if(mRetrofit ==null) {
            synchronized(RetrofitFactory::class) {
                if (mRetrofit == null) {
                    mRetrofit = Retrofit.Builder().addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                            .addConverterFactory(GsonConverterFactory.create())
                            .baseUrl(GlobalContent.BASEURL)
                            .build()
                }
            }
        }

        return mRetrofit?.create(service)
    }
}
    /**
     * Model層實現建立網路請求介面的例項
     */
class LoginModel:BaseModel,ILoginModel {
     var mService:LoginService = this.createService(LoginService.class);
    
 Override fun submitLoginInfo(String username, String password): Observable<BaseBean<String>>  {
        return mService.submitLoginInfo(username, password).compose(this.<BaseBean<String>>setThread());
    }
}

步驟4:採用Observable<…>形式 對 網路請求 進行封裝,傳送網路請求

在Model層建立

    /**
     * 設定執行緒的切換
     */
    fun <T> setThread(): ObservableTransformer<T, T> {
        return ObservableTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io())// 在IO執行緒進行網路請求
                    .observeOn(AndroidSchedulers.mainThread())//回到主執行緒 處理請求結果
        }
    }

在Presenter層

abstract class BasePresenter<T : IView> : IPresenter<T> {
    protected var mView: T? = null


   override fun attachView(view: T?) {
        this.mView = mView
    }

    override fun detachView() {
        if (this.mView != null) {
            mView = null
        }
    }

    override fun getView(): T? {
        return this.mView
    }
}

/**
 * 利用一個抽象類繼承BasePresenter來定義與Model層連線的方法,實現與View連線的介面,並在實現類呼叫方法和回撥介面
 */

abstract class AbstractLoginPresenter:BasePresenter<ILoginView>{
	abstract fun submitLoginInfo(String username,String password)
}

實現類Presenter

class LoginPresenter:AbstractLoginPresenter{
	private var mModel:IloginModel? = null
	constructor(){
	mModel = LoginModel()
	}
	override fun submitLoginInfo(String username, String password){
		mModel.submitLoginInfo(username,password)
			.subscribe(BaseObserver<String>() {
			override protected fun onFail(Throwable e){}
			override protected fun onSuccess(String data) {
                        getView().onLoginSuccess(data);
                    }
            override fun onCodeError() {
                        super.onCodeError();
                        getView().onLoginFail();
                    }
                })
    }
}

這樣基本就可以實現一個簡單的Retrofit 與 RxJava聯合使用