Kotlin basics--quickly get started with kotlin language development

kotlin foundation building

1. The most basic syntax of Kotlin

1.1 Variables

Var represents a mutable variable, and val represents an immutable variable. Note that they are not constants. The variable name is written in front and the type is written in the back. If the compiler can infer your type, then the type does not need to be declared.

var age:Int = 18
val name :String = "zhangsan"

The compiler automatically infers types.

var age = 18
val name = "zhangsan"

Null safe type compiler error

val name2: String = null

Insert image description here

If you still want to assign an initialization value

val name2: String? = null

Note: String and String? Are two completely different types. They cannot be assigned to each other.

Insert image description here

What if you still want to force compilation? Add two exclamation marks, !! means force. When you are sure that name2 is not null, you can forcefully assign it to name.

var age: Int = 18
var name: String = "zhangsan"
var name2: String? = null
fun main() {
    
    
    name = name2!!
}

But if we do the opposite, can we assign name to name2?

Yes, name is definitely not empty. name2 contains both nullable and non-nullable values, so it can be assigned a value.

var age: Int = 18
var name: String = "zhangsan"
var name2: String? = null
fun main() {
    
    
    name = name2!!
    name2 = name
}

1.2 Function

fun declaration function, printLen function name, str: String parameters and parameter types, : String return value, "12312123 str " template string, str" template string,s t r " Template string, symbol can refer to a variable and combine this variable into a new string.

fun printLen(str: String): String {
    
    
    println("12312123  $str")
    return str
}

have a test

var age: Int = 18
var name: String = "zhangsan"
var name2: String? = null
fun main() {
    
    
//    name = name2!!
//    name2 = name
    printLen("1231231")
}

fun printLen(str: String): String {
    
    
    println("adads $str")
    return str
}

Insert image description here

2. Kotlin is fully compatible with Java, can it be called casually?

2.1 Syntax changes

Java and Kotlin interaction syntax changes

Kotlin can be written in a file and not necessarily in a class.

//Utils.kt
fun echo(name: String) {
    
    
    println("$name")
}

Java must be written in a class. When calling the code in the kotlin file in java, the UtilsK suffix must be added with Kt. The kotlin file will be compiled into public static variables, so in the main function of java, the file name and function name can be called directly. .

// Main.java
public static void main(String[] args) {
    
    
	UtilsKt.echo("hello");
}

Kotlin’s special syntax, starting with object, followed by a class declaration

object Test {
    
    
    fun sayMessage(msg: String) {
    
    
        println(msg)
    }
}

transfer:

kotlin code

Test.sayMessage("hello")

java code

Test.INSTANCE.sayMessage("hello");

Next, the difference between the two languages ​​​​of our Kangkang class

java code

TestMain.class

kotlin code

TestMain::class.java

To call the Java class class, JavaMain, in kotlin, since this class is a Java class, the JavaMain::class.java suffix needs to be added with .java

java code

public class JavaMain {
    
    

}

kotlin code

fun testClass(clazz: Class<JavaMain>) {
    
    
    println(clazz.simpleName)
}
fun main() {
    
    
    testClass(JavaMain::class.java)
}

The following demonstrates calling a kotlin class. If it is a kotlin class, KClass needs to be declared like this. When KotlinMain::class is called, it is called directly. There is no need to add .java to the suffix because it is a kotlin class.

kotlin code

class KotlinMain {
    
    
}
import kotlin.reflect.KClass

fun testClass(clazz: Class<JavaMain>) {
    
    
    println(clazz.simpleName)
}

fun testClass(clazz: KClass<KotlinMain>) {
    
    
    println(clazz.simpleName)
}

fun main() {
    
    
    testClass(JavaMain::class.java)
    testClass(KotlinMain::class)
}

2.2 kotlin keyword processing

For example, in java, there is a variable named in

public class JavaMain {
    
    
    public static String in = "in";
}

In kotlin, in is a keyword. When calling java in kotlin, this variable cannot be called directly. Single quotes are required.

fun main() {
    
    
    println(JavaMain.`in`)
}

3. Common problems encountered by novices using Kotlin

3.1 Kotlin has no encapsulated classes

Take a look at the demo

java code

public class A implements AInterface {
    
    
    public static final A a = new A();
    @Override
    public void putNumber(int num) {
    
    
        System.out.println("int");
    }

    @Override
    public void putNumber(Integer num) {
    
    
        System.out.println("Integer");
    }
}
public interface AInterface {
    
    
    void putNumber(int num);
    void putNumber(Integer num);
}

kotlin code

fun main() {
    
    
    A.a.putNumber(123)
}

Output: int

Insert image description here

We found that the output is int instead of Interge, which means that when kotlin is running, it calls the method of the basic data parameters and does not execute the overloaded method of the encapsulated class.

3.2 Kotlin types are null value sensitive

java code

public class A {
    
    
    public static String format(String string) {
    
    
        return string.isEmpty() ? null : string;
    }
}

Call the format method in kotlin,

fun main() {
    
    
    val format = A.format("123")
    val format1: String = A.format("123")
    val format2: String = A.format("123")
}

Three return types,

The first type is automatically inferred. String with an exclamation mark is only present when Java and Kotlin interoperate. It cannot be declared manually. The compiler considers this type to be a Java type, but it is used in the Kotlin code, so it has exclamation mark
Insert image description here

Second, the three types are declared manually.

3.3 Kotlin does not have static variables and static methods

After we add the @JvmStatic annotation, we can call this method in Java like kotlin.

This method will also be compiled into a public static method after the code is compiled.

object Test {
    
    
    @JvmStatic
    fun sayMessage(msg: String) {
    
    
        println(msg)
    }
}

java code

Test.sayMessage("hello")

Instead of this

Test.INSTANCE.sayMessage("hello");

4. Can functions also be nested? Pay attention to this feature

4.1 Characteristic syntax of functions

Function example

fun echo(name: String) {
    
    
    println("$name")
}
fun echo(name: String ="zhangtao") {
    
    
    println("$name")
}
fun echo(name: String) = println("$name")

Parameters can have default values,

fun echo(name: String ="zhangtao") {
    
    
    println("$name")
}

Test, do not pass parameters, just take the default value

fun main() {
    
    
    echo()
}

Insert image description here

Advantages: It can greatly reduce the number of overloaded functions.

There is only one statement in the function body that can be directly assigned to this function.

fun echo(name: String) = println("$name")

4.2 Nested functions

Purpose:
A function that triggers recursion under certain conditions does not want to be accessed by an external function. The internal function can access the local variables of the external function.

fun function() {
    
    
    var str = "helle world"
    fun say(count: Int = 10) {
    
    
        println(str)
        if (count > 0) {
    
    
            say(count - 1)
        }
    }
    say()
}

test

fun main() {
    
    
    function()
}

Insert image description here

4.3 Extension functions

File is the class name, the method name of readText extension,

fun File.readText(charset: Charset = Charsets.UTF_8):
        String = readBytes().toString(charset)

test is the same as our normal calling method.

fun main() {
    
    
    val file = File("test.txt")
    println(file.readText())
}

How to use our extension functions in java.

java code

public class A {
    
    
    public static void main(String[] args) {
    
    
        File file = new File("test.txt");
        String s = FilesKt.readText(file, Charsets.UTF_8);
        System.out.println(s);
    }
}

Static analysis of extension functions:

demo: does not have polymorphic run types,

open class Animal
class Dog : Animal()

fun Animal.name() = "animal"
fun Dog.name() = "dog"

fun Animal.printfName(animal: Animal) {
    
    
    println(animal.name())
}
fun main() {
    
    
    Dog().printfName(Dog())
}

output

Insert image description here

Decompile and look at this code

animal's extension function name()

fun Animal.name() = "animal"  
//对应下面的反编译代码
@NotNull
   public static final String name(@NotNull Animal $this$name) {
    
    
      Intrinsics.checkNotNullParameter($this$name, "$this$name");
      return "animal";
   }

dog’s extension function name()

fun Dog.name() = "dog"
//对应下面的反编译代码
 @NotNull
   public static final String name(@NotNull Dog $this$name) {
    
    
      Intrinsics.checkNotNullParameter($this$name, "$this$name");
      return "dog";
   }

Animal extension function printfName

   fun Animal.printfName(animal: Animal) {
    
    
    println(animal.name())
	}
	//对应下面的反编译代码
	//@NotNull Animal $this$printfName  这个参数指的是扩展这个函数的那个对象
   public static final void printfName(@NotNull Animal $this$printfName, @NotNull Animal animal) {
    
    
      Intrinsics.checkNotNullParameter($this$printfName, "$this$printfName");
      Intrinsics.checkNotNullParameter(animal, "animal");
      String var2 = name(animal);
      System.out.println(var2);
   }
   public static final void main() {
    
    
      printfName((Animal)(new Dog()), (Animal)(new Dog()));
   }

After the main function is decompiled, (Animal)(new Dog()), (Animal)(new Dog()) the Dog object we passed in is actually forced to Animal, so the extension method name() of animal is finally output. .

4.4 The syntax of DSL’s basic Lambda closure

java code conventional writing method

public class A {
    
    
    public static void main(String[] args) {
    
    
        Thread thread = new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                
            }
        });
        thread.start();
    }
}

When writing Lambda, the Runnable object is omitted as a pair of brackets and arrows are added.

public class A {
    
    
    public static void main(String[] args) {
    
    
        Thread thread = new Thread(() -> {
    
    

        });
        thread.start();
    }
}

kotlin code

fun main() {
    
    
    val thread = Thread({
    
     -> Unit })
    thread.start()
}

If the Lambda has no parameters, the arrow symbol can be omitted

fun main() {
    
    
    val thread = Thread({
    
    })
    thread.start()
}

If the Lambda is the last parameter of the function, you can put the curly braces outside the parentheses

fun main() {
    
    
    val thread = Thread(){
    
    }
    thread.start()
}

If the function has only one parameter and this parameter is a Lambda, you can omit the parentheses

fun main() {
    
    
    val thread = Thread {
    
    }
    thread.start()
}

Lambda closure declaration

fun main() {
    
    
    echo.invoke("123")
    echo("123")
}
val echo = {
    
     name: String ->
    println(name)
}

The parameters are online, and there can only be a maximum of 22 parameters.

fun main() {
    
    
    lambdaA(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
}

val lambdaA = {
    
     a1: Int, a2: Int, a3: Int, a4: Int, a5: Int, a6: Int, a7: Int, a8: Int, a9: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, a16: Int, a17: Int, a18: Int, a19: Int, a20: Int, a21: Int, a22: Int ->
    println("!23")
}

Output: !23

If we add one more parameter for a total of 23 parameters, an exception will be thrown.

Lambda will be compiled into an anonymous inner class, Function23, with 23 parameters

There are only 22 parameters in the source code

Insert image description here

solve:
Insert image description here

Manually define a Function23.

4.5 Higher-order functions

kotlin code

fun main() {
    
    
    onlyif(true) {
    
    
        println("打印日志")
    }
}

fun onlyif(isDebug: Boolean, block: () -> Unit) {
    
    
    if (isDebug) block()
}

Key Point: Functions are “first-class citizens”

fun main() {
    
    
    val runnable = Runnable {
    
    
        println("run")
    }
    val function: () -> Unit
    function = runnable::run

    onlyif(true, function)
}

fun onlyif(isDebug: Boolean, block: () -> Unit) {
    
    
    if (isDebug) block()
}

Output: run

Normal execution

4.6 Inline functions

Optimize code with inlining

Kotlin's Lambda is an anonymous object

You can use inline to modify the method, so that when the method is compiled, the method call will be disassembled into statement calls, thus reducing the creation of unnecessary objects.

fun main() {
    
    
    val runnable = Runnable {
    
    
        println("run")
    }
    val function: () -> Unit
    function = runnable::run

    onlyif(true, function)
}

inline fun onlyif(isDebug: Boolean, block: () -> Unit) {
    
    
    if (isDebug) block()
}

Plus inline decompilation

public static final void onlyif(boolean isDebug, @NotNull Function0 block) {
    
    
      int $i$f$onlyif = 0;
      Intrinsics.checkNotNullParameter(block, "block");
      if (isDebug) {
    
    
         block.invoke();
      }

   }

main function, statement call

public static final void main() {
    
    
      Runnable runnable = (Runnable)null.INSTANCE;
      Function0 function = null;
      function = (Function0)(new Function0(runnable) {
    
    
         // $FF: synthetic method
         // $FF: bridge method
         public Object invoke() {
    
    
            this.invoke();
            return Unit.INSTANCE;
         }

         public final void invoke() {
    
    
            ((Runnable)this.receiver).run();
         }
      });
      boolean isDebug$iv = true;
      int $i$f$onlyif = false;
      function.invoke();
   }

No decompilation

public static final void onlyif(boolean isDebug, @NotNull Function0 block) {
    
    
      Intrinsics.checkNotNullParameter(block, "block");
      if (isDebug) {
    
    
         block.invoke();
      }

   }

main function, method call

 public static final void main() {
    
    
      Runnable runnable = (Runnable)null.INSTANCE;
      Function0 function = null;
      function = (Function0)(new Function0(runnable) {
    
    
         // $FF: synthetic method
         // $FF: bridge method
         public Object invoke() {
    
    
            this.invoke();
            return Unit.INSTANCE;
         }

         public final void invoke() {
    
    
            ((Runnable)this.receiver).run();
         }
      });
      onlyif(true, function);
   }

Reduce the generation of temporary objects. inline will only be used to modify higher-order functions.

5. Classes and Objects

1. Constructor

Kotlin classes are public final by default, and init is executed when the constructor is called.

open class MainActivity(var int: Int) : AppCompatActivity(), View.OnClickListener {
    
    
    init {
    
    
        println("loge====")
    }
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
    }

    override fun onClick(v: View?) {
    
    

    }
}

Kotlin constructor, the hidden primary constructor follows the class name, the secondary constructor, indirectly or directly inherits the primary constructor or the constructor of the parent class.

class MyView : View {
    
    
    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )
}

2. Access modifiers

private

protected

public

internal: The same module can call each other.

3. Companion objects

kotlin code

class StringUtils {
    
    
    companion object {
    
    
        fun ifEmpty(str: String): Boolean {
    
    
            return "" == str
        }
    }
}

kotlin code call

fun main() {
    
    
    StringUtils.ifEmpty("123")
}

java code call

public class A {
    
    
    public static void main(String[] args) {
    
    
        StringUtils.Companion.ifEmpty("213123")
    }
}

4. Singleton class

class Single private constructor() {
    
    
    companion object {
    
    
        fun get(): Single {
    
    
            return Holder.instance
        }
    }

    private object Holder {
    
    
        val instance = Single()
    }
}

fun main() {
    
    
    Single.get()
}

5. Dynamic proxy

Dynamic proxy for classes

fun main() {
    
    
    Zoo(Dog()).back()
}

interface Animal {
    
    
    fun back()
}

class Dog : Animal {
    
    
    override fun back() {
    
    
        println("12312")
    }
}

class Zoo(animal: Animal) : Animal by animal

Output 12312

Suppose we are in Zoo

class Zoo(animal: Animal) : Animal by animal{
    
    
    override fun back() {
    
    
        println("Zoo")
    }
}

Output: Zoo

6. Kotlin-specific classes

data class

public final
getter()/setter()
toString(),hashCode(),equals(),copy()

data class User(var id: Int, var name: String)

enum class

Sealed type

sealed class TestOne {
    
    
    object A : TestOne()
    object B : TestOne()
    object C : TestOne()
    object D : TestOne()
}

6. Advanced features

1. Deconstruction

operator: marks a function as overloading an operator or implementing a convention

class User(var age: Int, var name: String) {
    
    
    operator fun component1() = age
    operator fun component2() = name
}

fun main() {
    
    
    val user = User(12, "name")
    val (age, name) = user
    println(age)
    println(name)
}

Commonly used in traversing maps

fun main() {
    
    

    val map = mapOf<String, String>("key" to "key", "value" to "value")
    for ((k, v) in map) {
    
    
        println("$k, $v")
    }
}

2. Loop and set operators

Five commonly used loops

fun main() {
    
    
    for (i in 1..10) {
    
    
        println(i)
    }
    for (i in 1 until 10) {
    
    
        println(i)
    }
    for (i in 10 downTo 1) {
    
    
        println(i)
    }
    for (i in 1..10 step 2) {
    
    
        println(i)
    }
    repeat(10) {
    
    
        println(it)
    }

}

Traverse the collection, deconstruct

fun main() {
    
    
    val list = arrayListOf<String>("a", "b", "c")
    for (str in list) {
    
    
        println(str)
    }
    for ((index, str) in list.withIndex()) {
    
    
        println("$index $str")
    }
    
}

3. Set operators

set operator

fun main() {
    
    
    val arrayListOf = arrayListOf<Char>('a', 'b', 'c', 'd')
    val a = arrayListOf.map {
    
     it - 'a' }.filter {
    
     it > 0 }.find {
    
     it > 1 }
}

4. Scope functions

Five commonly used functions

run{},with(T){},let{},apply{},also{}.

import javax.jws.soap.SOAPBinding.Use

data class User(var name: String)

fun main() {
    
    
    val user = User("1231")
    //let与run都会返回闭包的执行结果,区别在于let有闭包参数,而run没有闭包参数
    val let = user.let {
    
     user: User -> "let::${
      
      user.javaClass}" }
    println(let)
    val run = user.run {
    
     "run::${
      
      this.javaClass}" }
    println(run)

    //also与apply都不返回闭包的执行结果,区别在于aso有闭包参数,而apply没有闭包参数
    user.also {
    
     println("also::${
      
      it.javaClass}") }
    user.apply {
    
     println("apply::${
      
      this.javaClass}") }

    //takeIf 的闭包返回一个判断结果,为false时,takeIf函数会返回空
    // takeUnless 与 takeIf 刚好相反, 闭包的判断结果,为true时函数会返回空
    user.takeIf {
    
     it.name.length > 0 }?.also {
    
     println("姓名为${
      
      it.name}") } ?: println("姓名为空")
    user.takeUnless {
    
     it.name.length > 0 }?.also {
    
     println("姓名为空") } ?: println("姓名${
      
      user.name}")

    //重复执行当前闭包
    repeat(5) {
    
    
        println(user.name)
        println(it)
    }

    //with比较特殊,
    //不是以扩展方法的形式存在的,而是一个顶级函数
    with(user) {
    
    
        this.name = "with"
    }
}

5. Infix expression, operator overloading

A function is declared as an infix function only when it is used for two objects with similar roles. Recommended examples: and, to, zip. Counterexample: add.
If a method modifies its receiver, do not declare it infixed.

6. DSL

7. Kotlin extension library

1. kotlinx.coroutines

What is coroutine

Improve program running efficiency by improving CPU utilization and reducing thread switching.

Controllable: coroutines can initiate subtasks that can be controlled

Lightweight: coroutines are very small and occupy less resources than threads

Syntactic sugar: Make multitasking or multithread switching no longer use callback syntax

Start coroutine

runBlocking: T, //Used to perform coroutine tasks,
usually only used to start the outermost coroutine

launch: Job, //used to execute coroutine tasks

async/await: Deferred, //used to execute coroutine tasks

package com.chk.myexpandlist

import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
    
    
    runBlocking<Unit> {
    
    
        val launch = launch {
    
    
            repeat(1000) {
    
     i ->
                println("挂起中 $i。。。")
                delay(500L)
            }
        }
        var job2 = async {
    
    
            delay(500L)
            return@async "hello"
        }
        println(job2.await())
        delay(1300L)
        println("main:主线程等待中")
        launch.cancel()
        launch.join()
        println("main:即将完成退出")
    }
}

There are a total of four parameters in the source code of launch in the three startup methods.

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
)

context: current program context, coroutine and coroutine switching parameters, CoroutineContext scheduler, can be placed in a thread,

start: How to start the coroutine,

block: started coroutine,

demo

private val okHttpClient = OkHttpClient()
private val request = Request.Builder().url("https//baidu.com").get().build()
fun displayDashboard(textView: TextView) = runBlocking {
    
    
    withContext(Dispatchers.Main) {
    
    
        textView.text = withContext(Dispatchers.Default) {
    
    
            okHttpClient.newCall(request).execute().body()?.string()
        }
    }
}

java code

public class Dashboard {
    
    
    private final OkHttpClient okHttpClient = new OkHttpClient();
    private final Request request = new Request.Builder().url("https://baidu.com").get().build();
    private final Handler handler = new Handler(Looper.getMainLooper());

    public void display(final TextView textView) {
    
    
        okHttpClient.newCall(request).enqueue(new Callback() {
    
    
            @Override
            public void onFailure(Call call, IOException e) {
    
    

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
    
    
                final String string = response.body().string();
                handler.post(() -> textView.setText(string));
            }
        });
    }
}

test

class TestMainActivity : AppCompatActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test_main)
    }

    fun test2(view: View) {
    
    
        val tvContent = findViewById<TextView>(R.id.mContent)
        Dashboard().display(tvContent)
        displayDashboard(tvContent)
    }
    fun test1(view: View) {
    
    
        runBlocking {
    
    
            withContext(Dispatchers.Main) {
    
    
                println("在主线程中启动一个协程," + Thread.currentThread().name)
            }
        }

    }
}

xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:text="hello world"
            android:id="@+id/mContent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/btnTestThread"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="test1"
            android:text="测试1" />

        <Button
            android:text="测试2"
            android:onClick="test2"
            android:id="@+id/btnTestCoroutine"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</ScrollView>
object AndroidCommonPool : CoroutineDispatcher() {
    
    
    override fun dispatch(context: CoroutineContext, block: Runnable) {
    
    
        AsyncTask.THREAD_POOL_EXECUTOR.execute(block)
    }
}

suspend keyword:

// suspend, the function modified by suspend can only be called by the function modified by suspend
// Because the function (or lambda) modified by suspend will have an extra parameter type called Continuation after being compiled, // The asynchronous call of the coroutine is essentially a callback

suspend fun getHtml(): String {
    
    
    return withContext(AndroidCommonPool) {
    
    
            URL("http://baidu.com").readText()
        }
}

Call getHtml in java

public class JavaActivity extends AppCompatActivity {
    
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        LaunchCoroutineKt.getHtml(new Continuation<String>() {
    
    
            @NonNull
            @Override
            public CoroutineContext getContext() {
    
    
                return null;
            }

            @Override
            public void resumeWith(@NonNull Object o) {
    
    

            }
        });
    }
}

Special way to start coroutine

buildSequence/yield: Sequence

buildlterator: lterator

produce : Channel

2. kotlinx-io


```kotlin
object AndroidCommonPool : CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        AsyncTask.THREAD_POOL_EXECUTOR.execute(block)
    }
}

suspend keyword:

// suspend, the function modified by suspend can only be called by the function modified by suspend
// Because the function (or lambda) modified by suspend will have an extra parameter type called Continuation after being compiled, // The asynchronous call of the coroutine is essentially a callback

suspend fun getHtml(): String {
    
    
    return withContext(AndroidCommonPool) {
    
    
            URL("http://baidu.com").readText()
        }
}

Call getHtml in java

public class JavaActivity extends AppCompatActivity {
    
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        LaunchCoroutineKt.getHtml(new Continuation<String>() {
    
    
            @NonNull
            @Override
            public CoroutineContext getContext() {
    
    
                return null;
            }

            @Override
            public void resumeWith(@NonNull Object o) {
    
    

            }
        });
    }
}

Special way to start coroutine

buildSequence/yield: Sequence

buildlterator: lterator

produce : Channel

2. kotlinx-io

3. Android KTX

Guess you like

Origin blog.csdn.net/weixin_46039528/article/details/131217611