当前位置:网站首页>Kotlin collaboration - simple use of collaboration
Kotlin collaboration - simple use of collaboration
2022-06-13 06:26:00 【m0_ forty-seven million nine hundred and fourteen thousand one 】
One . Introduction to the association
1. brief introduction
Concurrency is a concurrent design pattern , You can go to Android It is used on the platform to simplify asynchronous code execution . coroutines It's in version. 1.3 Add to Kotlin Of , It is based on established concepts from other languages .
stay Android On , Collaborative processes help manage long-running tasks , If the management is wrong , These tasks may block the main thread and cause the application to be unresponsive . There are more than... Professional developers using collaborative processes 50% Of people reported that the use of collaborative processes has improved work efficiency . This topic describes how to use Kotlin The collaborative process solves the following problems , So that you can write clearer 、 More concise application code .
2. characteristic
The synergy is that we are Android Recommended solution for asynchronous programming on . Features worthy of attention include :
- Light weight : You can run multiple coroutines on a single thread , Because the program supports Hang up , The running thread will not block . Hang saves memory than blocking , It also supports multiple parallel operations .
- Less memory leakage : Use Structured concurrency Mechanism performs multiple operations within a scope .
- Built in cancellation support : Cancel The operation will be automatically propagated throughout the collaboration hierarchy in operation .
- Jetpack Integrate : many Jetpack The libraries all contain the Expand . Some libraries also offer their own Process scope , Can be used by you for structured concurrency .
Two . The simple application of coprocess
1. Write... In collaboration Retrofit Case study
Import dependencies first
// The process depends on
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC-native-mt'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC-native-mt'
//retrofit rely on
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'// Entity class
data class User(
val `data`: List<Data>,
val errorCode: Int,
val errorMsg: String
)
data class Data(
val category: String,
val icon: String,
val id: Int,
val link: String,
val name: String,
val order: Int,
val visible: Int
)//Retrofit Network request
val userServiceApi: UserServiceApi by lazy {
val retrofit = Retrofit.Builder()
.client(OkHttpClient.Builder().addInterceptor {
it.proceed(
it.request()
).apply {
Log.d("jason", "request:${code()}")
}
}.build()).baseUrl("https://www.wanandroid.com/friend/").addConverterFactory(MoshiConverterFactory.create())
.build()
retrofit.create(UserServiceApi::class.java)
}
interface UserServiceApi {
@GET("json")
// Hang up
suspend fun User() :User
}class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text.text="Jack"
button.also {
it.setOnClickListener {
// Coroutine builder The main thread
GlobalScope.launch(Dispatchers.Main) {
// Task scheduler Sub thread
val user= withContext(Dispatchers.IO){
userServiceApi.User()
}
text.text="address:${user?.data?.get(0)?.category}"
}
}
}
}
}This is the end of the example , Next we one One explanation .
2. Suspension and recovery of collaboration
Basic operations of general functions include :invoke( or call) and return, The program added suspend and res
ume:
suspend One Also known as suspend or pause , Used to pause the execution of the current program , And save all local variables ;
resume One Used to allow a suspended process to resume execution from where it was suspended .
class MainActivity3 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text.text="Jack"
button.also {
it.setOnClickListener {
// Coroutine builder The main thread
GlobalScope.launch(Dispatchers.Main) {
// Suspend method
getUser()
}
}
}
}
// Pending keywords
private suspend fun getUser(){
val user=get()
show(user)
}
private fun show(user:User){
text.text="address:${user?.data?.get(0)?.category}"
} // Task scheduler Sub thread
private suspend fun get()= withContext(Dispatchers.IO){
userServiceApi.User()
}
}By using suspend The modified code , Note that the sub method uses suspend The parent method has to add suspend . Also use suspend Keyword can only be used within a coroutine or other suspended functions .
3. Hang and block
class MainActivity4 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text.text="Jack"
// Suspending does not block the main thread , And will record and complete the tasks you go to
button.also {
it.setOnClickListener {
// Coroutine builder The main thread
GlobalScope.launch(Dispatchers.Main) {
// Delay It has the function of suspending
delay(10000)
Log.d("delay","${Thread.currentThread().name} after delay")
}
//sleep Will block the main thread ,
// Thread.sleep(10000)
// Log.d("delay","${Thread.currentThread().name} after sleep")
}
}
}
}Here, by using delay, Each time you click the button, you will open a collaboration process to initiate a task , too 10 How many times will you print after seconds , And it doesn't block the main thread . And the bottom sleep Will block the main thread , Yes ANR Danger .
4. The basic writing method of the cooperative process
class MainActivity5 : AppCompatActivity() {
/**
*
*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text.text="Jack"
// This is the base function at the bottom of the coroutine
// Synergetics Is also a suspend function
val createCoroutine = suspend {
5 // Incoming value
}.createCoroutine(object : Continuation<Int> {
// Collaboration context
override val context: CoroutineContext = EmptyCoroutineContext
// The callback for the completion of the collaboration execution
override fun resumeWith(result: Result<Int>) {
//result Execution results of the coordination process
Log.i("resumeWith", "$result ")
}
})
// Start the coroutines
createCoroutine.resume(Unit)
}
}5. The scheduler of the process
All processes must be completed in Run in the scheduler .
Dispatchers.Main : Android The main thread on is used to handle UI Interaction and some lightweight tasks
Dispatchers.IO : Non main threads are designed for disk and network IO the
Dispatchers.Default : Non main thread to CPU Intensive tasks are optimized
6. Mission leaks
When a collaborative task is lost , Unable to track , Will cause memory 、CPI-R Disk and other resources are wasted , Even hair
Send a useless network request , This situation is called Mission leaks .
In order to avoid the coprocess leak ,Kot|in Introduced Structured concurrency mechanism .
1. Structured concurrency
Using structured concurrency can :
Cancel the task : Cancel a task when it is no longer needed .
Tracking mission : When a task is being performed , Track it . Send out the wrong signal : When the coroutine fails , An error signal indicates that an error has occurred .
7.CoroutineScope
Defining a coroutine must specify its CoroutineScope, It tracks all collaborations , It can also Cancel
All the processes started by it .
Common related API Yes :
GlobalScope, The life cycle is process Grade , Even if Activity or Fragment Has been destroyed , The collaboration process is still being implemented .
MainScope, stay Activity Use in , Can be in onDestroy() Cancel the cooperation process .
viewModeIScope, Only in ViewM0de| Use in , binding ViewM0de| Life cycle of .
IifecycIeScope, Only in Activity、Fragment Use in , Will bind Activity and Fragment Life cycle of .
class MainActivity6 : AppCompatActivity() {
private var nametext :TextView?=null;
private var mainScope = MainScope()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//text.text="Jack"
nametext=findViewById(R.id.text)
button.apply {
setOnClickListener {
mainScope.launch {
//User Function uses suspend, so it will automatically enable a child thread request
val user = userServiceApi.User()
nametext?.text="address:${user?.data?.get(0)?.category}"
}
}
}
override fun onDestroy() {
super.onDestroy()
// Cancel mainScope The task of
mainScope.cancel()
}
}You can write like this
class MainActivity6 : AppCompatActivity(),CoroutineScope by MainScope() {
private var nametext :TextView?=null;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
nametext=findViewById(R.id.text)
button.apply {
setOnClickListener {
launch {
//User Function uses suspend, so it will automatically enable a child thread request
val user = userServiceApi.User()
nametext?.text = "address:${user?.data?.get(0)?.category}"
}
}
}
}
override fun onDestroy() {
super.onDestroy()
// Cancel mainScope The task of
cancel()
}
}There are two kinds of MainScope Two ways of writing
3、 ... and . Xie Cheng started
Here is an example to use : coroutines +Retrofit+ViewModel+LiveData+DataBinding
Let me explain first , Data classes and Retrofit The encapsulated class and the first column used by the child use a .
First configure DataBinding And rely on
android {
dataBinding {
enabled = true
}
} implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC-native-mt'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC-native-mt'class UserRepository{
// Suspend function Return the data
suspend fun getUser():User{
return userServiceApi.User()
}
}class MainViewModel : ViewModel() {
val userLiveData= MediatorLiveData<User>()
private val UserRepository=UserRepository()
fun getUser(){
//viewModelScope binding viewModel Life cycle of
viewModelScope.launch {
userLiveData.value= UserRepository.getUser()
}
}
}<layout 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">
<data>
<variable
name="viewModel"
type="com.example.ktolincorutine.viewModel.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.userLiveData.data.get(0).category}"
android:id="@+id/text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="224dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.52"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>class MainActivity7 : AppCompatActivity() {
private val mainViewModel:MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
binding.lifecycleOwner=this;
binding.viewModel=mainViewModel
text.text="Jack"
binding.button.setOnClickListener {
mainViewModel.getUser()
}
}
} demonstration :
边栏推荐
- [solution] camunda deployment process should point to a running platform rest API
- Kotlin basic definition class, initialization and inheritance
- [DP 01 backpack]
- Analysis of synchronized
- Wechat applet (pull-down refresh data) novice to
- Omron Ping replaces the large domestic product jy-v640 semiconductor wafer box reader
- Dart class inherits and implements mixed operators
- Adding classes dynamically in uni app
- 【案例】一个超级好用的工具 —— 给程序员用的计算器
- 【2022高考季】作为一个过来人想说的话
猜你喜欢

The processing and application of C language to documents
![[DP 01 backpack]](/img/be/1e5295684ead652eebfb72ab0be47a.jpg)
[DP 01 backpack]

El form form verification

MFS explanation (V) -- MFS metadata log server installation and configuration

Kotlin basic definition class, initialization and inheritance

JVM Foundation

欧姆龙平替国产大货—JY-V640半导体晶元盒读写器

Relationship between fragment lifecycle and activity
![[one · data 𞓜 simple implementation of the leading two-way circular linked list]](/img/a2/08f55012cd815190db76237f013961.png)
[one · data 𞓜 simple implementation of the leading two-way circular linked list]

Echart rectangular tree diagram: simple implementation of rectangular tree diagram
随机推荐
本地文件秒搜工具 Everything
[JS] handwriting call(), apply(), bind()
Recent problems
SSM framework integration -- > simple background management
347. top k high frequency elements heap sort + bucket sort +map
App performance test: (IV) power
[case] a super easy-to-use tool -- a calculator for programmers
Free screen recording software captura download and installation
synchronized浅析
Differences among concurrent, parallel, serial, synchronous and asynchronous
超有范的 logo 在线设计制作工具
Echart折线图:多条折线图每次仅展示一条
Local file search tool everything
Basic knowledge of knowledge map
【js】var、let、const
Regular verification of mobile phone number, landline email ID card
Analysis of 43 cases of MATLAB neural network: Chapter 11 optimization of continuous Hopfield Neural Network -- optimization calculation of traveling salesman problem
Omron Ping replaces the large domestic product jy-v640 semiconductor wafer box reader
Simple use of event bus
Applet disable native top