为了账号安全,请及时绑定邮箱和手机立即绑定

Kotlin实战--Retrofit网络模型

标签:
Java Kotlin

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: Class<JavaStudent>) { }

// 全部都用 kt
fun  showClass2(clazz: KClass<KtStudent>) { }

  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:Class<T>):T{
            val mOkHttpClient=OkHttpClient().newBuilder()
                .readTimeout(10000,TimeUnit.SECONDS)
                .connectTimeout(10000,TimeUnit.SECONDS)
                .writeTimeout(10000,TimeUnit.SECONDS)
                .build()

            val mRetrofit=Retrofit.Builder()
                .baseUrl("https://www.wanandroid.com")
                //请求方
                .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)
                    :Observable<ResponseWrapper<LoginResponse>>

}
复制代码

2.3、将返回结果公共部分进行抽取

服务端数据的返回格式,

{
data:{},
errorCode:100,
errorMsg:""
}
复制代码

只有data是不确定的,我们用泛型来接收它

data class ResponseWrapper<T>(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 APIResponse<T>(val context:Context):Observer<ResponseWrapper<T>> {


    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: ResponseWrapper<T>) {
        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:APIResponse<LoginResponse>(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
链接:https://juejin.cn/post/6950576674740109325
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
数据库工程师
手记
粉丝
42
获赞与收藏
202

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消