kotlin大法:协程它不香吗(网络交互篇)

andriod项目中网络请求使用kotlinRetrofit的最优雅方式,抛弃Callback,抛弃RxJava,接受协程java

源码传送门: android-kotlin-retrofit-wrapandroid

网上一大堆都是Retrofit+Rxjava或者使用回调方式,其实使用协程才是真的简单好用git


android项目如今基本都是用kotlin开发,而kotlin的优点显而易见,其中的协程也是一大利器github

网络交互通常使用okhttp+Retrofit,而在okhttp4.0+已经使用了kotlin做为维护语言,Retrofit在2.6.0版本也开始支持了挂起(suspend)修饰符,这使得android项目中使用kotlin个Retrofit进行网络交互尤其方便数据库

该项目内容为kotlin协程配合Retrofit实现网络请求的一个示例json

Step0: android项目中加入kotlin及其协程的支持

  • 项目根目录build.gradle文件中加入:api

    buildscript {
          ext.kotlin_version = '1.3.50'
          ext.kotlin_coroutines = '1.3.2'
          
      	...
    
          dependencies {
              classpath 'com.android.tools.build:gradle:3.5.0'
              classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
              ...
          }
      }
    复制代码
  • app目录下的build.gradle中加入支持并添加依赖:网络

    apply plugin: 'kotlin-android'
      apply plugin: 'kotlin-android-extensions'
    
      dependencies {
          implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
          implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines"
          implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines"
          
      	implementation 'androidx.core:core-ktx:1.1.0'
          implementation 'androidx.appcompat:appcompat:1.1.0'
      
          implementation 'com.squareup.retrofit2:retrofit:2.6.2'
          implementation "com.squareup.okhttp3:okhttp:4.2.0"
          implementation "com.squareup.okhttp3:logging-interceptor:4.2.0"
      	
      	...
      }
    复制代码

Step1: 对Retrofit的简单封装 详见RetrofitWrap.kt

/**
 * 是否开启打印日志,默认关闭
 */
fun init(baseUrl: String, debugEnable: Boolean = false) {
    instance.retrofit = Retrofit.Builder().apply {
        baseUrl(baseUrl)
        client(okhttpClient(debugEnable))
        addConverterFactory(StringConverterFactory.create())
    }.build()
}

/**
 * 获取API服务
 */
fun <T> service(service: Class<T>): T {
    if (instance.retrofit != null) {
        return instance.retrofit!!.create(service)
    } else {
        throw IllegalStateException("请先调用RetrofitWrap.init()方法进行初始化")
    }
}
复制代码

就两个对外方法:架构

  • init:初始化,配置baseUrl和是否打印日志,其余参数能够基于源码修改加入
  • service:获取服务实例,传入定义api的接口类,而后调用对应方法便可完成数据请求

Step2: 根据业务定义网络交互方法,例如API.kt

interface API {
    @GET("test.json")
    suspend fun info(): String
}
复制代码

使用Example,详见TestActivity.kt

  • 完整示例:app

    class TestActivity : AppCompatActivity(), CoroutineScope by MainScope() {
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_main)
      
              RetrofitWrap.init("https://okfood.vip/", false)
      
              btn.setOnClickListener {
                  content.text = "加载中..."
                  launch {
                      val data = withContext(Dispatchers.IO) {
                          RetrofitWrap.service(API::class.java).info()
                      }
                      content.text = if (TextUtils.isEmpty(data)) "error" else data
                  }
              }
          }
      
          override fun onDestroy() {
              super.onDestroy()
              cancel()
          }
      }
    复制代码
  • 说明

    • 初始化RetrofitWrap.init须要放置在第一次请求网络以前,能够是application中
    • 不建议使用GlobalScopelaunch一个协程任务,android中便于生命周期的管理提供了MainScope,在页面销毁处调用cancel()避免内存泄露

闲外话

  • 该项目内容仅是一种极简使用方式的展现,具体项目中,能够根据项目架构作对应调整,好比加上使用ViewModel以及LiveData等

  • 同理,实现方式也能够用于数据库的操做,毕竟网络和数据库都是android数据存储的方式

相关文章
相关标签/搜索