协程高效、轻量级,可以解决大并发的问题,但是协程的真正魅力是,最大的成都简化异步并发任务,用同步代码写出异步的效果。
mProgressDialog = ProgressDialog(this)
mProgressDialog.setTitle("请求服务器中...")
mProgressDialog.show()
mTextView.setText("请求服务器中...")
thread {
var call = RetrofitClient.instance.initRetrofit(WanAndroidAPI::class.java)
.login("lpf666", "123456")
val result = call.execute()
var msg = mHandler.obtainMessage()
msg.obj = result.body()?.data
mHandler.sendMessage(msg)
}
val mHandler = Handler(Looper.getMainLooper()) {
val result = it.obj as UserInfo
mTextView.text = result.toString() // 更新控件 UI
mProgressDialog?.dismiss() // 隐藏加载框
false
}
mMainScope.launch {
Log.d("lpf", Thread.currentThread().name)
mProgressDialog = ProgressDialog(this@Coroutines2Activity)
mProgressDialog.setTitle("请求服务器中...")
mProgressDialog.show()
mTextView.setText("请求服务器中...")
//可以完美解决网络嵌套的问题
var result = RetrofitClient.instance.initRetrofit(WanAndroidAPI::class.java)
.loginCoroutine("lpf666", "123456")
mTextView.text = result.data.toString()// 更新控件 UI
mProgressDialog?.dismiss() // 隐藏加载框
}
协程的方式这样就实现了,不需要创建子线程,不需要发消息,代码非常简洁,网络层只需要加上suspen关键字就可以。
协程可以解决异步回调的问题、协程同样可以解决多层网络嵌套的问题。
使用过程中注意的点:
协程可以轻松进行线程切换
mMainScope.launch(Dispatchers.Main) {
}
设置Dispatchers.IO()就是子线程了。
执行协程部分的代码逻辑,会自动挂起到IO线程,执行完成会自动恢复Main线程。
每一次从主线程到IO线程,都是一次协程挂起(suspend)
每一次从IO恢复到主线程,都是一次协程的(resume)
挂起,只是将程序执行流程转移到其他线程,并未阻塞主线程。
var result = RetrofitClient.instance.initRetrofit(WanAndroidAPI::class.java)
.loginCoroutine("lpf666", "123456")
以这行代码为例=号的左边的部分就是主线程,右边的部分就是子线程,这是协程自动挂起的。
使用协程会看到小图标:
协程还需要遵守颜色规则,这一点很关键
将执行协程的代码反编译之后,可以看到一个Continuation
@kotlin.SinceKotlin public interface Continuation<in T> {
public abstract val context: kotlin.coroutines.CoroutineContext
public abstract fun resumeWith(result: kotlin.Result<T>): kotlin.Unit
}
其实本质上也是callback的方式,只是换成了Continuation,继续连续,通过resumeWith来恢复。
Continuation是继续执行后后面的意思,继续做接下来没做完的事情。
其实就是状态机的状态label在记录状态,label=0之后就完成了所有的逻辑。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBCM0Ahe-1652886827099)(C:/Users/刘静盼/AppData/Roaming/Typora/typora-user-images/image-20220518224600055.png)]
Activity、Fragment通过ViewModel解决数据跟View耦合的问题,将逻辑拆分到几个不同的model中去,只需要关心数据的变化就可以,采用数据驱动UI的方式,Activity需要再处理View的刷新逻辑,只需要绑定ViewModel就可以。
ViewModel获取数据,如果是本地数据直接获取Room数据库的数据。
如果是网络数据,直接通过retrofit请求网络。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WXvKAaqc-1652886827100)(https://gitee.com/weifeng_xixi/images/raw/master/img/image-20220518224303769.png)]