Kotlin實戰--Retrofit網路模型

pswyjz發表於2021-09-09

1、Java和Kotlin互相呼叫之間的注意事項

1、解決關鍵字衝突

public class JavaStudent {

    public static String in = "INNNNNN";

    public String getString() {
        return null;
    }
}
複製程式碼

我們知道in在kotlin裡是區間的意思,但是在Java中是可以用in來定義屬性的,在Kotlin裡直接呼叫會出現衝突的 圖片描述 解決衝突

fun main() {
    
    // 解決衝突問題
    println(JavaStudent.`in`)
   }
複製程式碼

2、Kotlin呼叫Java帶有返回值的方法,Kotlin不確定Java會返回什麼,所以你得用安全的方式來接收Java返回的值 圖片描述

 // 錯誤的示範 JavaStudent().string.length 
 //正確的示範 
    var str: String ? = JavaStudent().string
    println(str?.length)
複製程式碼

3.介面回撥的寫法不同

public interface JavaCallback {

    void show(String info);

}

public class JavaManager {

    public void setCallback(JavaCallback javaCallback) {
        javaCallback.show("愛碼士");
    }
}
複製程式碼

Kotlin呼叫Java的Callback

// TODO kt 使用 Java Callback
    // 第一種寫法
    JavaManager().setCallback(JavaCallback {
        println(it)
    })

    // 第二種寫法
    JavaManager().setCallback(object : JavaCallback{
        override fun show(info: String?) {
            println(info)
        }
    })

    // 第三種寫法
    val callback = JavaCallback {
        println(it)
    }
    JavaManager().setCallback(callback)

    // 第四種寫法
    val callback2 = object : JavaCallback{
        override fun show(info: String?) {
            println(info)
        }
    }
    JavaManager().setCallback(callback2)
複製程式碼

Kotlin 呼叫Kotlin的CallBack

interface KTCallback {

    fun show(name: String)

}


class KtManager {

    fun setCallback(callback: KTCallback) {
        callback.show("Kt Derry")
    }

}


    // TODO kt 使用 tk Callback
    // 1
    KtManager().setCallback(object : KTCallback{
        override fun show(name: String) {
        }
    })

    // 2
    val c = object : KTCallback{
        override fun show(name: String) {  }
    }
    KtManager().setCallback(c)

	   // Kt不能像Java一樣的寫法
    /*KtManager().setCallback(KTCallback{

    })*/
複製程式碼

4、形參裡的Class物件

// 行參裡面 java
fun showClass(clazz: ClassJavaStudent>) { }

// 全部都用 kt
fun  showClass2(clazz: KClassKtStudent>) { }

  showClass(JavaStudent::class.java)//傳遞Java的Class

    showClass2(KtStudent::class)//傳遞Kotlin的Class
複製程式碼

2、Retrofit網路模型

使用WanAndroid的伺服器的API完成一個登入功能

2.1、初始化OkHttpClient

class APIClient {
    private object Holder{
        val INSTANCE=APIClient()
    }
    companion object{
        val instance=Holder.INSTANCE
    }

    /***
     * 例項化WanAndroidAPI
     */
    fun T> instanceRetrofit(apiInterface:ClassT>):T{
            val mOkHttpClient=OkHttpClient().newBuilder()
                .readTimeout(10000,TimeUnit.SECONDS)
                .connectTimeout(10000,TimeUnit.SECONDS)
                .writeTimeout(10000,TimeUnit.SECONDS)
                .build()

            val mRetrofit=Retrofit.Builder()
                .baseUrl("")
                //請求方
                .client(mOkHttpClient)
                //響應方
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
            return mRetrofit.create(apiInterface)
    }
}
複製程式碼

2.2、構建WanAndroidAPI介面

interface WanAndroidAPI {
    /***
     * 登入API
     */
    @POST("/user/login")
    @FormUrlEncoded
    fun loginAction(@Field("username")username:String,
                    @Field("password")password:String)
                    :ObservableResponseWrapperLoginResponse>>

}
複製程式碼

2.3、將返回結果公共部分進行抽取

服務端資料的返回格式,

{
data:{},
errorCode:100,
errorMsg:""
}
複製程式碼

只有data是不確定的,我們用泛型來接收它

data class ResponseWrapperT>(val data:T,var errorCode:Int,val errorMsg:String)
複製程式碼

登入介面返回資訊的Bean

//泛型的萬用字元 java裡是?  Kotlin裡是*
//允許伺服器欄位為null,在欄位後面加?
data class LoginResponse(val admin:Boolean,
                         val chapterTops:List*>,
                         val collectIds:List*>,
                         val email:String?,
                         val icon :String?,
                         val id: String?,
                         val nickname: String?,
                         val password: String?,
                         val publicName: String?,
                         val token: String?,
                         val type: Int,
                         val username: String?)
                         
複製程式碼

2.4、自定義RxJava運算子,對結果進行處理,如果異常和data==null,就走onFailure(),否則就走onSuccess,並在請求開始和結束的時候加入載入框

/***
 * RxJava 自定義運算子
 */
abstract class APIResponseT>(val context:Context):ObserverResponseWrapperT>> {


    private var isShow=true
    //次構造
    constructor(context: Context,isShow:Boolean= false):this(context){
        this.isShow=isShow
    }
    abstract fun onSuccess(data:T?)
    abstract fun onFailure(errorMsg:String?)

    override fun onComplete() {
        // 取消載入
        LoadingDialog.cancel()
    }

    override fun onSubscribe(d: Disposable) {
        if(isShow){
            LoadingDialog.show(context)
        }
    }

    override fun onNext(t: ResponseWrapperT>) {
        if(t.data==null){
            onFailure("msg:${t.errorMsg}")
        }else{
            onSuccess( t.data)
        }
    }

    override fun onError(e: Throwable) {
        LoadingDialog.cancel()
        onFailure(e.message)
    }
}
複製程式碼

2.5、點選登入進行網路請求

  private fun initView() {
       user_login_bt.setOnClickListener {
           doLogin()
       }
    }

    private fun doLogin() {
        val userName=user_phone_et.text.toString()
        val pwd=user_password_et.text.toString()
        APIClient.instance.instanceRetrofit(WanAndroidAPI::class.java)
            .loginAction(userName,pwd)
            .subscribeOn(Schedulers.io())//在IO執行緒進行網路請求
            .observeOn(AndroidSchedulers.mainThread())//在主執行緒更新UI
            .subscribe(object:APIResponseLoginResponse>(this){
                override fun onSuccess(data: LoginResponse?) {
                   Toast.makeText(this@LoginActivity,"登陸成功嘿嘿~",Toast.LENGTH_SHORT).show()
                }

                override fun onFailure(errorMsg: String?) {
//                    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                    Toast.makeText(this@LoginActivity,errorMsg,Toast.LENGTH_SHORT).show()
                }

            })
//            .
    }

作者:愛碼士趙Sir
連結:
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/755/viewspace-2807216/,如需轉載,請註明出處,否則將追究法律責任。

相關文章