Introduction to Android | introduction to Kotlin collaboration

Posted by lead2gold on Fri, 12 Nov 2021 18:25:49 +0100

Android officials recommend using concurrency to deal with asynchronous problems.

Characteristics of collaborative process:

  • Lightweight: multiple coroutines can be run on a single thread. The process supports suspension, which will not block the thread running the process. Suspending saves memory than blocking and supports multiple parallel operations.
  • Less memory leaks: use structured concurrency to perform multiple operations within a scope.
  • Built in cancellation support: the cancellation operation will be automatically propagated within the whole collaboration hierarchy in operation.
  • Jetpack integration: many jetpack libraries contain extensions that provide comprehensive collaboration support. Some libraries also provide their own collaboration scope, which can be used for structured concurrency.
Example

Firstly, Kotlin and coprocess need to be introduced into the project. Then use the process to initiate the network request.

introduce:
Introducing kotlin into Android project, refer to   Android project uses kotlin

With Kt, the co process is introduced

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9" // Synergetic process
}

Start process

Unlike the Kotlin project, which uses GlobalScope directly, this example uses a collaboration in the ViewModel. viewModelScope is required.

The following CorVm1 inherits the ViewModel.

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope // introduce
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class CorVm1 : ViewModel() {

    companion object {
        const val TAG = "rfDevCorVm1"
    }

    fun cor1() {
        viewModelScope.launch { Log.d(TAG, "Not specified dispatcher ${Thread.currentThread()}") }
    }
}

Calling the cor1() method in the button click listener, you can see that the association is in the main thread.

Not specified dispatcher Thread[main,5,main]

Since this collaboration is started through viewModelScope, it is executed within the scope of ViewModel. If the ViewModel is destroyed because the user leaves the screen, the viewModelScope will be automatically cancelled and all running collaborations will be cancelled.

The launch() method can specify the thread to run. You can pass in Dispatchers to specify the thread to run.

Let's take a brief look at Dispatchers in the kotlinx.coroutines package. It has four attributes:

  • Default, default
  • Main, the main thread is specified in Android
  • Unconfined, no thread specified
  • IO, specify IO thread

Are started by clicking on events

// CorVm1.kt

fun ioCor() {
    viewModelScope.launch(Dispatchers.IO) {
        Log.d(TAG, "IO Synergetic process ${Thread.currentThread()}")
    }
}

fun defaultCor() {
    viewModelScope.launch(Dispatchers.Default) {
        Log.d(TAG, "Default Synergetic process ${Thread.currentThread()}")
    }
}

fun mainCor() {
    viewModelScope.launch(Dispatchers.Main) { Log.d(TAG, "Main Synergetic process ${Thread.currentThread()}") }
}

fun unconfinedCor() {
    viewModelScope.launch(Dispatchers.Unconfined) {
        Log.d(TAG, "Unconfined Synergetic process ${Thread.currentThread()}")
    }
}

Run log

IO Synergetic process Thread[DefaultDispatcher-worker-1,5,main]
Main Synergetic process Thread[main,5,main]
Default Synergetic process Thread[DefaultDispatcher-worker-1,5,main]
Unconfined Synergetic process Thread[main,5,main]

As can be seen from the above comparison, if you want to use background threads, you can consider Dispatchers.IO. Default also uses the DefaultDispatcher-worker-1 thread.

Simulate network request

Network requests cannot be made in the main thread. We put the requests on the thread reserved for IO operations. Some messages are sent with MutableLiveData.

// CorVm1.kt
val info1LiveData: MutableLiveData<String> = MutableLiveData()

private fun reqGet() {
    info1LiveData.value = "Initiate request"
    viewModelScope.launch(Dispatchers.IO) {
        val url = URL("https://www.baidu.com/s?wd=abc")
        try {
            val conn = url.openConnection() as HttpURLConnection
            conn.requestMethod = "GET"
            conn.connectTimeout = 10 * 1000
            conn.setRequestProperty("Cache-Control", "max-age=0")
            conn.doOutput = true
            val code = conn.responseCode
            if (code == 200) {
                val baos = ByteArrayOutputStream()
                val inputStream: InputStream = conn.inputStream
                val inputS = ByteArray(1024)
                var len: Int
                while (inputStream.read(inputS).also { len = it } > -1) {
                    baos.write(inputS, 0, len)
                }
                val content = String(baos.toByteArray())
                baos.close()
                inputStream.close()
                conn.disconnect()
                info1LiveData.postValue(content)
                Log.d(TAG, "net1: $content")
            } else {
                info1LiveData.postValue("Network request error $conn")
                Log.e(TAG, "net1: Network request error $conn")
            }
        } catch (e: Exception) {
            Log.e(TAG, "reqGet: ", e)
        }
    }
}

Take a look at the flow of this network request

  1. Call the reqGet() function from the main thread
  2. viewModelScope.launch(Dispatchers.IO) sends a network request on the collaboration
  3. Carry out network operation in the cooperation process. Send the results.

kotlin collaborative process related knowledge points

1. Basis of collaborative process

  • Your first collaboration program
  • Bridging the blocking and non blocking world
  • Waiting for a task
  • Structured concurrency
  • Scope builder
  • Extraction function reconstruction
  • ......

2. Cancellation and timeout

  • Cancel the execution of the collaboration
  • Cancellation is collaborative
  • Make calculation code cancelable
  • Release resources in finally
  • Run code blocks that cannot be cancelled
  • overtime

3. Access

  • Channel foundation
  • Close and iterate channels
  • Build channel producer
  • The Conduit
  • Use the prime of the pipe
  • Fan out
  • Fan in
  • Buffered channel
  • The channel is fair
  • timer channel

4. Combine pending functions

  • Default sequential call
  • Using async concurrency
  • Lazy start async
  • async style functions
  • Structured concurrency using async

5. Collaboration context and scheduler

  • Scheduler and thread
  • Unrestricted scheduler vs restricted scheduler
  • Debugging procedures and threads
  • Jump between different threads
  • Tasks in context
  • Subprocess
  • Responsibilities of parent process
  • Name the coroutine for debugging
  • Combining elements in context
  • Cancel by explicit task
  • Thread local data

6. Exception handling

  • Abnormal propagation
  • CoroutineExceptionHandler
  • Cancellation and exception
  • Abnormal aggregation
  • supervise

7. select expression

  • select in channel
  • select when the channel is closed
  • Select to send
  • Select delay value
  • Switch on delay value channel

8. Shared variable state and concurrency

  • problem
  • volatile doesn't help
  • Thread safe data structure
  • Limit threads at fine granularity
  • Restrict threads with coarse granularity
  • mutex
  • Actors

[Kotlin getting started to proficient in a full range of video references]

Topics: Android kotlin