当前位置:网站首页>Detailed explanation of kotlin collaboration lanch
Detailed explanation of kotlin collaboration lanch
2022-06-24 13:35:00 【Hua Weiyun】
@[TOC](kotlin coroutines lanch Detailed explanation )
Preface
Use pure code Add The way of annotating , You can understand the source code faster
If you like , Please give me a compliment , In the later stage, we will continue to explain in depth
One 、 What is the schedule ?
1. Most developers compare collaborative processes to : Thread encapsulation framework , From a macro perspective , This makes sense
2. A coroutine is a bit like a lightweight thread
3. From the perspective of inclusion relationship , The relationship between coroutine and thread , It's kind of like “ The relationship between thread and process ”, After all , A coroutine cannot run out of a thread
4. Although a coroutine cannot run without a thread , But you can switch between different threads
Two 、 The traditional way to complete asynchronous network loading and collaborative process comparison
2.1: Traditional way to complete asynchronous task network loading
Next, simulate login through an interface , To realize the traditional step-by-step task network loading login scenario
The code is as follows :LoginRegisterResponseWrapper
data class LoginRegisterResponseWrapper<T>(val data: T, val errorCode: Int, val errorMsg: String)The code is as follows :LoginRegisterResponse
data class LoginRegisterResponse( 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?)Define an interface The code is as follows :WanAndroidAPI
interface WanAndroidAPI {// TODO Here's the traditional way API /** https://www.wanandroid.com/blog/show/2 * Sign in API * username=Derry-vip&password=123456 */ @POST("/user/login") @FormUrlEncoded fun loginAction( @Field("username") username: String, @Field("password") password: String ) : Call<LoginRegisterResponseWrapper<LoginRegisterResponse>> // Return value }Interface implementation The code is as follows :APIClient
class APIClient { /** * Single case */ private object Holder { val INSTANCE = APIClient() } companion object { // The derived val instance = Holder.INSTANCE } fun <T> instanceRetrofit(apiInstance: Class<T>): T {// OkHttpClient Request server val mOkHttpClient = OkHttpClient().newBuilder().apply { readTimeout(10000, TimeUnit.SECONDS) // Add timeout connectTimeout(10000, TimeUnit.SECONDS) // Add connection timeout writeTimeout(10000, TimeUnit.SECONDS) // Add write timeout }.build() val retrofit = Retrofit.Builder() .baseUrl("https://www.wanandroid.com") // Requesting party ← .client(mOkHttpClient) // Responder → // Response Things about Come back .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // RxJava To deal with it .addConverterFactory(GsonConverterFactory.create()) // Gson Parsing --- JavaBean .build() return retrofit.create(apiInstance) }}XML The code is as follows
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.MainActivity"> <TextView android:id="@+id/textview" android:text=" Start thread " android:layout_width="match_parent" android:layout_height="wrap_content" tools:ignore="MissingConstraints" /> <Button android:id="@+id/button" android:onClick="startRequest" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=" Network request " app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="OnClick" /></androidx.constraintlayout.widget.ConstraintLayout>Specific function realization , Just look at the code , There are a lot of comments
The code is as follows : MainActivity
class MainActivity : AppCompatActivity() { private var mProgressDialog: ProgressDialog? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun startRequest(view: View){ mProgressDialog = ProgressDialog(this) mProgressDialog?.setTitle(" Request server ...") mProgressDialog?.show()// TODO First step : Asynchronous thread on , Request server object: Thread(){ override fun run() { super.run() Thread.sleep(2000) // Simulate a two second loading time val loginResult = APIClient.instance.instanceRetrofit(WanAndroidAPI::class.java) .loginAction("Derry-vip", "123456") val result: LoginRegisterResponseWrapper<LoginRegisterResponse>? = loginResult.execute().body()// Switch to the main thread , to update UI Put the final javaBean Send to Handler val msg = mHandler.obtainMessage() msg.obj = result mHandler.sendMessage(msg) } }.start() } // TODO The second step : The main thread updates UI val mHandler = Handler(Looper.getMainLooper()){// as Type conversion val result = it.obj as LoginRegisterResponseWrapper<LoginRegisterResponse> textview.text = result.data.toString() // Update controls UI mProgressDialog?.hide() false }}The code above implements , It is a traditional asynchronous loading operation . You need to start an asynchronous thread first , Then put the data of successful login , Then give it to the main thread to do UI Update operation for .
2.2: The asynchronous task network loading is completed in the way of collaborative process
And then realize a collaborative process
modify WanAndroidAPI The interface inside , add to suspend keyword , The code is as follows :
@POST("/user/login") @FormUrlEncoded suspend fun loginActionCoroutine( @Field("username") username: String, @Field("password") password: String ) : LoginRegisterResponseWrapper<LoginRegisterResponse> // Return value modify MainActivity The code in , The code is as follows :
class MainActivity1 : AppCompatActivity() { private var mProgressDialog: ProgressDialog? = null private val main = MainScope() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun startRequest(view: View) { mProgressDialog = ProgressDialog(this) mProgressDialog?.setTitle(" Request server ...") mProgressDialog?.show()// launch stay Android When used in , The default is IO Threads , So it needs to be changed to Main Threads (Dispatchers.Main ) main.launch(Dispatchers.Main) { // 1. Hang out to execute asynchronous threads 2. After the operation , Restore the main thread val result = APIClient.instance.instanceRetrofit(WanAndroidAPI::class.java) .loginActionCoroutine("Derry-vip", "123456")// to update UI textview.text = result.data.toString() mProgressDialog?.hide() } } override fun onDestroy() { super.onDestroy() main.cancel() }}Is it much simpler ? There is no need to create asynchronous threads , Then give it to the main thread to modify UI, But directly launch Hang out to perform asynchronous operations , After the operation is completed, directly restore to the main thread
This is just a simple example of a layer 1 callback , Imagine some , If the boss asks us to implement a three-tier callback ,30 Layer callback , How painful it will be for us to use the traditional treatment , Now let's do it .
2.3: The traditional way is to complete the three-tier callback
Write a callback interface first The code is as follows ResponseCallback
/** * After impersonating the request server , Corresponding result information */interface ResponseCallback { /** * Request server Loading successful */ fun responseSuccess(serverResponseInfo: String) /** * Request server Loading failed */ fun responseError(serverResponseErrorMsg: String)}Write three more asynchronous threads that simulate data requests The code is as follows :
/** * first floor * Request load [ User data ] * * responseCallback [ Callback to the external interface ] */private fun requestLoadUser(responseCallback: ResponseCallback) { val isLoadSuccess = true // Loading successful or Failed flag object : Thread() { override fun run() { super.run() try { sleep(3000L) // Simulation of the request The resulting time-consuming if (isLoadSuccess) { responseCallback.responseSuccess(" Load into [ User data ] Information set ") } else { responseCallback.responseSuccess(" load [ User data ], Loading failed , Server down ") } } catch (e: InstantiationException) { e.printStackTrace() } } }.start()}/** * The second floor * Request load [ User asset data ] * * responseCallback [ Callback to the external interface ] */private fun requestLoadUserAssets(responseCallback: ResponseCallback) { val isLoadSuccess = true // Loading successful or Failed flag object : Thread() { override fun run() { super.run() try { sleep(3000L) if (isLoadSuccess) { responseCallback.responseSuccess(" Load into [ User asset data ] Information set ") } else { responseCallback.responseError(" load [ User asset data ], Loading failed , Server down ") } } catch (e: InstantiationException) { e.printStackTrace() } } }.start()}/** * The third level * Request load [ User asset details data ] * * responseCallback [ Callback to the external interface ] */private fun requestLoadUserAssetsDetails(responseCallback: ResponseCallback) { val isLoadSuccess = true // Loading successful or Failed flag object : Thread() { override fun run() { super.run() try { sleep(3000L) if (isLoadSuccess) { responseCallback.responseSuccess(" Load into [ User asset data ] Information set ") } else { responseCallback.responseError(" load [ User asset data ], Loading failed , Server down ") } } catch (e: InstantiationException) { e.printStackTrace() } } }.start()}Specific function realization , Just look at the code , Nothing to say
The code is as follows : MainActivity
class MainActivity2 : AppCompatActivity() { private var mProgressDialog: ProgressDialog? = null private val main = MainScope() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun startRequest(view: View) { mProgressDialog = ProgressDialog(this) mProgressDialog?.setTitle(" Request server ...") mProgressDialog?.show()// TODO Execute first Asynchronous requests 1 requestLoadUser(object : ResponseCallback { override fun responseSuccess(serverResponseInfo: String) {// From asynchronous Switch to the main thread , to update UI val handler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { super.handleMessage(msg) textview.text = serverResponseInfo textview.setTextColor(Color.GRAY)// TODO Execute first Asynchronous requests 2 requestLoadUserAssets(object : ResponseCallback { override fun responseSuccess(serverResponseInfo: String) { val handler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { super.handleMessage(msg) textview.text = serverResponseInfo textview.setTextColor(Color.RED) // TODO Execute first Asynchronous requests 3 requestLoadUserAssetsDetails(object : ResponseCallback { override fun responseSuccess(serverResponseInfo: String) { val handler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { super.handleMessage(msg) textview.text = serverResponseInfo textview.setTextColor(Color.BLUE) mProgressDialog?.hide() } } handler.sendEmptyMessage(0) } override fun responseError(serverResponseErrorMsg: String) {// TODO The logic of failure is not written } }) } } handler.sendEmptyMessage(0) } override fun responseError(serverResponseErrorMsg: String) {// TODO The logic of failure is not written } }) } } handler.sendEmptyMessage(0) } override fun responseError(serverResponseErrorMsg: String) {// TODO The logic of failure is not written } }) }} Unlimited Nesting , It reminds me flutter Nested traps in .
Look again. Use coroutines Implementation of three-tier callback
2.4: Solve the three-layer callback band by means of collaborative process
First define three methods , Start an asynchronous thread respectively . The code is as follows :
/** * Request load [ User data ] * * suspend It's a reminder , Remind users , The current function is a pending function , May perform abnormal operations */private suspend fun requestLoadUser(): String{ val isLoadSuccess = true // Loading successful , and , Loading failed , The tag // This coroutine can ensure asynchronous execution withContext(Dispatchers.IO){ delay(3000) // Impersonate request server , The resulting time-consuming } if (isLoadSuccess){ return " Load into [ User data ] Information set " }else{ return " load [ User data ], Loading failed , Server down " }}/** * Request load [ User asset data ] */private suspend fun requestLoadUserAssets(): String{ val isLoadSuccess = true // Loading successful , and , Loading failed , The tag // This coroutine can ensure asynchronous execution withContext(Dispatchers.IO){ delay(3000) // Impersonate request server , The resulting time-consuming } if (isLoadSuccess){ return " Load into [ User asset data ] Information set " }else{ return " load [ User asset data ], Loading failed , Server down " }}/** * Request load [ User asset details data ] */private suspend fun requestLoadUserAssetsDetails(): String{ val isLoadSuccess = true // Loading successful , and , Loading failed , The tag // This coroutine can ensure asynchronous execution withContext(Dispatchers.IO){ delay(3000) // Impersonate request server , The resulting time-consuming } if (isLoadSuccess){ return " Load into [ User asset details data ] Information set " }else{ return " load [ User asset details data ], Loading failed , Server down " }}MainActivity The specific implementation of the code is as follows :
class MainActivity : AppCompatActivity() { private var mProgressDialog: ProgressDialog? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun startRequest(view: View) { mProgressDialog = ProgressDialog(this) mProgressDialog?.setTitle(" Request server ...") mProgressDialog?.show()// Dispatchers.Main Wrap a layer Handler Switch main thread GlobalScope.launch(Dispatchers.Main) {// TODO Execute first Asynchronous requests 1 var serverResponseInfo = requestLoadUser() textview.text = serverResponseInfo // to update UI textview.setTextColor(Color.YELLOW) // to update UI// TODO to update UI After completion Asynchronous requests 2 serverResponseInfo = requestLoadUserAssets() textview.text = serverResponseInfo // to update UI textview.setTextColor(Color.RED) // to update UI// TODO to update UI After completion Asynchronous requests 3 serverResponseInfo = requestLoadUserAssetsDetails() textview.text = serverResponseInfo // to update UI textview.setTextColor(Color.BLUE) // to update UI mProgressDialog?.hide() } }}See here , Is it easy to find ?
summary
Isn't the process easy ” Efficient “,” Light weight “ Are we going to use a collaborative process ?
answer : In fact, the real charm of Xiecheng is , Minimize asynchronous concurrent tasks , Write asynchronous effects in synchronous code
🤩
️
边栏推荐
- 强化学习之父Richard Sutton论文:追寻智能决策者的通用模型
- 硬件开发笔记(六): 硬件开发基本流程,制作一个USB转RS232的模块(五):创建USB封装库并关联原理图元器件
- Why does the kubernetes environment require that bridge NF call iptables be enabled?
- Preparation and operation & Maintenance Guide for 'high concurrency & high performance & high availability service program'
- 工业物联网(IIoT)的八个主要趋势
- Evolution of the message module of the play live series (3)
- 谁是鱼谁是饵?红队视角下蜜罐识别方式汇总
- 物联网?快来看 Arduino 上云啦
- Implement Domain Driven Design - use ABP framework - update operational entities
- 首席信息安全官仍然会犯的漏洞管理错误
猜你喜欢

nifi从入门到实战(保姆级教程)——环境篇

3. Caller 服务调用 - dapr

Comparator sort functional interface

"I, an idiot, have recruited a bunch of programmers who can only" Google "

华为AppLinking中统一链接的创建和使用

Creation and use of unified links in Huawei applinking

LVGL库入门教程 - 颜色和图像

一文讲透研发效能!您关心的问题都在

Nifi from introduction to practice (nanny level tutorial) - environment

工业物联网(IIoT)的八个主要趋势
随机推荐
What is the difference between sap QM and UD for inspection lots with hum?
敏捷之道 | 敏捷开发真的过时了么?
Cmput 379 explanation
如何避免严重网络安全事故的发生?
Appium installation
CVPR 2022 | 美团技术团队精选论文解读
我開導一個朋友的一些話以及我個人對《六祖壇經》的一點感悟
"I, an idiot, have recruited a bunch of programmers who can only" Google "
一文讲透研发效能!您关心的问题都在
Use abp Zero builds a third-party login module (I): Principles
39 - read XML node and attribute values
数据科学家面临的七大挑战及解决方法
Sphere, openai and ai21 jointly publish the best practice guidelines for deployment models
hands-on-data-analysis 第三单元 模型搭建和评估
Ask a question about SQL view
CVPR 2022 - Interpretation of selected papers of meituan technical team
How to create a new empty branch in the web development process of easyrtc?
About the hacked database
Summary of the process of restoring damaged data in MySQL database
Getting started with the go Cobra command line tool