【问题标题】:Coroutine GlobalScope triggered with delay延迟触发的协程 GlobalScope
【发布时间】:2019-09-02 09:02:48
【问题描述】:

如果处理时间超过 250 毫秒,我想显示进度对话框。

我正在尝试使用协程来做到这一点。我的问题是我是否删除“延迟(250)”行,它总是先运行dismissProgressDialog()然后运行showProgressDialog()。我认为这是关于 GlobalScope.launch(Dispatchers.Main) 因为当我删除它时,它会按预期首先运行 showProgressDialog()。

fun showProgressDialog() =
    GlobalScope.launch(Dispatchers.Main) {
        if (!customDialog.isShowing) {
            forceCloseLoading = false

            LogUtils.e("progress show before delay")
            delay(250)
            LogUtils.e("progress show after delay")

            if (!forceCloseLoading) {
                customDialog.show()
            }
        }
    }

fun dismissProgressDialog() {
    forceCloseLoading = true
    LogUtils.e("progress dismiss")

    try {
        if (customDialog.isShowing) {
            customDialog.dismiss()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }

}

这是我的 logcat 输出:

progress dismiss
progress show before delay
progress show after delay

如果处理时间超过 250 毫秒,我如何才能显示进度对话框?

【问题讨论】:

  • 能否也分享一下调用showProgressDialogdismissProgressDialog的代码,好吗?看起来有些东西阻塞了您的主线程并阻止 showProgressDialog 被安排运行。您可以使用launch(Dispatchers.Main, start=CoroutineState.UNDISPATCHED) 强制它立即运行直到在delay() 暂停。

标签: android kotlin coroutine kotlin-coroutines


【解决方案1】:

下面的代码将显示一个按钮,如果工作时间超过 250 毫秒,按下该按钮将触发一个对话框。比赛时,会显示一个小吃店,向用户发出工作完成的信号。如果我对您的理解正确,这应该演示您要求的功能。

class MainActivity : AppCompatActivity() {
    // Create a scope for out coroutines to run on, with the coroutine context Unconfined.
    private val scope: CoroutineScope = CoroutineScope(Dispatchers.Unconfined)

    private lateinit var customDialogBuilder: AlertDialog.Builder
    private lateinit var customDialog: AlertDialog

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Create a dialog to display when task is in progress
        customDialogBuilder = AlertDialog.Builder(this)
            .setMessage("Working on it...")
            .setTitle("Loading...")

        // Set the listener where a coroutine job is launched. The job starts another job which will
        // take somewhere between 1..800 ms to complete. The parent job waits 250ms then checks if
        // the child job is completed, if not it displays the dialog.
        btn_process.setOnClickListener {
            scope.launch {

                // Launch a job with the work we are waiting on.
                val job = launchWork()
                delay(250)

                // Check if the job is still active, if so show the dialog.
                if (job.isActive) {
                    runOnUiThread {
                        customDialog = customDialogBuilder.show()
                    }
                }
            }
        }
    }

    private fun launchWork(): Job {
        return scope.launch {
            // Simulate some work.
            val workTime = Random.nextLong(1, 800)
            delay(workTime)

            runOnUiThread {
                // Dismiss dialog when done.
                if (customDialog.isShowing) {
                    customDialog.dismiss()
                }
                // Show some feedback that the work is done.
                Snackbar
                    .make(layout_root, "Work finished in ${workTime}ms", Snackbar.LENGTH_LONG)
                    .show()
            }
        }
    }
}

布局,activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:id="@+id/layout_root"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_process"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Process" />

</LinearLayout>

build.gradle(应用程序):

dependencies {

    ...

    def coroutines_version = "1.3.1"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

    implementation 'com.google.android.material:material:1.0.0' // For snackbar

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    相关资源
    最近更新 更多