android - Lambda无法在Kotlin中进行多线程操作

标签 android kotlin

我有一个简单的工作线程类,该类具有一个称为execute的函数,该函数将任务添加到ConcurrentLinkedQueue对象。

package com.bignerdranch.android.handler
import android.util.Log
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicBoolean

class SimpleWorker : Thread(TAG) {

    lateinit var taskQueue: ConcurrentLinkedQueue<Runnable>
    lateinit var alive: AtomicBoolean

    companion object {
        val TAG = "SimpleWorker"
    }

    init {
        start() // call start method of thread
    }

    override fun run() {
        alive = AtomicBoolean(true)
        taskQueue = ConcurrentLinkedQueue()

        while (alive.get()) { // .get returns the value
            val task: Runnable = taskQueue.poll()
            if(task != null) { // if there is a task in queue
                task.run() // run the task
            }
        }
        Log.i(TAG, "SimpleWorker Terminated")
    }

    fun execute(task: Runnable): SimpleWorker {
        taskQueue.add(task)
        return this
    }

    fun quit() {
        alive.set(false)
    }
}

我可以在Java中将匿名部分作为Lambda运行,但在Kotlin中不能作为Lambda运行。这是主要部分:
package com.bignerdranch.android.handler

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private var worker: SimpleWorker? = null
    private var tvMessage: TextView? = null
    private val handler: Handler = object : Handler(Looper.getMainLooper()) {
        // using anonymous class outside of arguments
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            tvMessage!!.text = msg.obj as String
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tvMessage = findViewById(R.id.tv_message)
        worker = SimpleWorker() // thread starts
        worker.execute({
            try {
                Thread.sleep(1000)
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
            val message = Message.obtain()
            message.obj = "Task 1 completed"
            handler.sendMessage(message)
        }).execute({
            try {
                Thread.sleep(500)
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
            val message = Message.obtain()
            message.obj = "Task 2 completed"
            handler.sendMessage(message)
        }).execute({
            try {
                Thread.sleep(1000)
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
            val message = Message.obtain()
            message.obj = "Task 3 completed"
            handler.sendMessage(message)
        })
    }
}

执行lambda用红色排列,编译器告诉我它需要返回Runnable。这对我来说没有任何意义,因为这些方法返回一个SimpleWorker。

感谢大家的帮助。

最佳答案

问题是,当您在Kotlin中执行worker.execute({ })时,您正在使用的不是Kotlin Lambda引用,而不是@FunctionalInterface。之所以在Java中而不是在Kotlin中起作用,是因为Runnable上面带有@FunctionalInterface批注,因此您可以用Java lambda替换Runnable
还要看看this相关问题。

关于android - Lambda无法在Kotlin中进行多线程操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59563838/

相关文章:

git - 在 Android Studio 中将文件(使用 Git 跟踪)从 Java 转换为 Kotlin

java - 如何将数组列表中的值从 AsyncTask 类发送到 Android 中的另一个类?

android - 如何在 Android 手机图库中实用地获取图像的所有详细信息

scala - 在 Scala 中通过委托(delegate)装饰(如 kotlin)

kotlin - Kotlin 中的数据类平等

unit-testing - Koin的KotlinTest:InvocationTargetException

android - 如何使用 Android Webview 在后台播放 YouTube?

java - 如何使这项工作正常工作并在退出时保存并在重新加载时恢复

javascript - 如何在 React Native 中分享社交网络上的深层链接

java - 通过 LLVM 前端编译的 Kotlin/Native 和 Java 字节码有什么区别?