andriod项目中网络请求使用kotlin
和Retrofit
的最优雅方式,抛弃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
项目根目录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"
...
}
复制代码
/**
* 是否开启打印日志,默认关闭
*/
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的接口类,而后调用对应方法便可完成数据请求interface API {
@GET("test.json")
suspend fun info(): String
}
复制代码
完整示例: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中GlobalScope
去launch
一个协程任务,android中便于生命周期的管理提供了MainScope
,在页面销毁处调用cancel()
避免内存泄露该项目内容仅是一种极简使用方式的展现,具体项目中,能够根据项目架构作对应调整,好比加上使用ViewModel以及LiveData等
同理,实现方式也能够用于数据库的操做,毕竟网络和数据库都是android数据存储的方式