不用协程发起网络请求
先定义一个发起请求的单例类
object HttpUtil {
fun sendHttp(url: String, callback: Callback){//使用Okhttp发起请求
thread {
val client = OkHttpClient()
val request = Request.Builder()
.url(url)
.build()
client.newCall(request).enqueue(callback)
}
}
}
发起请求
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fir.setOnClickListener {//访问百度主页
HttpUtil.sendHttp("https://www.baidu.com",object : okhttp3.Callback{ //匿名类实现接口
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
shows(response.body()?.string())
}
override fun onFailure(call: okhttp3.Call, e: IOException) {
shows(e.toString())
}
})
}
sec.setOnClickListener{//访问谷歌主页
HttpUtil.sendHttp("https://www.google.com",object : okhttp3.Callback{ //匿名类实现接口
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
shows(response.body()?.string())
}
override fun onFailure(call: okhttp3.Call, e: IOException) {
shows(e.toString())
}
})
}
fun shows(data:String?) {
runOnUiThread {
text.text = data
}
}
}
使用协程发起网络请求
同样定义一个单例类
object HttpUtil {
suspend fun request(url: String):String {
return suspendCoroutine {
continuation ->
thread {
try {
val client = OkHttpClient()
val request = Request.Builder()
.url(url)
.build()
val response = client.newCall(request).execute()
continuation.resume(response.body()!!.string())
}
catch (e: Exception) {
continuation.resumeWithException(e)
}
}
}
}
}
发起请求
class MainActivity : AppCompatActivity() {
val scope = MainScope()//结构化管理协程
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fir.setOnClickListener {
scope.launch {
try {
text.text = HttpUtil.request("https://www.baidu.com")
}catch (e: Exception){
text.text = e.toString()
}
}
}
sec.setOnClickListener{
scope.launch {
try {
text.text = HttpUtil.request("https://www.google.com")
}catch (e: Exception){
text.text = e.toString()
}
}
}
}
override fun onDestroy() {
super.onDestroy()
scope.cancel()//取消协程
}
}
从上面的代码可以明显感受到用协程可以简化网络请求的回调,使用传统的方法每次发起请求都要写一次接口回调,而使用协程每次发起网络请求只用写一个简单的try-catch捕捉异常就可以。
协程能够简化网络请求的原因主要在于挂起函数,使用挂起函数能够暂时将协程从当前线程脱离,等到网络请求完成,再恢复协程,继续在线程上运行。
这里主要用到了suspendCoroutine()挂起函数,此函数接收一个Lambda表达式,输入是一个Continuation类参数,调用该类的resume()方法可以恢复协程。