首页 > 解决方案 > Kotlin:如何在不冻结 UI 的情况下延迟 Android 中的代码

问题描述

我正在尝试延迟我尝试过的 Kotlin 中的代码

Thread.sleep(1000)

但它冻结了用户界面。

有人知道为什么会发生这种情况以及如何在不冻结 UI 的情况下延迟?

标签: kotlinui-threadbackground-thread

解决方案


什么地方出了错

用法Thread.sleep(...)

Thread.sleep 使当前线程暂停执行一段指定的时间。这是使处理器时间可用于应用程序的其他线程或可能在计算机系统上运行的其他应用程序的有效方法。

对于 OP(原始海报/提问者)的澄清:

它冻结了 UI,有人知道为什么会这样吗?

正如上面 Java 官方文档中提到的,您在 UI 中遇到了某种冻结,因为您在Main Thread中调用了它。

主线程,或者如果你在 Android 中做你的事情,它通常被称为UI 线程

在 Android 平台上,应用程序默认在一个线程上运行。这个线程称为UI 线程。它通常被称为是因为这个单线程显示用户界面并监听用户与应用程序交互时发生的事件。

如果不使用多线程 API(例如Runnable, Coroutines, RxJava)的帮助,您将自动Thread.sleep(1000)UI 线程上调用,这就是您遇到这种“UI 冻结”体验的原因,因为其他UI Operations人被阻止访问线程,因为您已经调用暂停它。

以及如何在不冻结ui的情况下延迟?

利用可用 API 的强大功能进行多线程处理,到目前为止,最好从以下选项开始:

1. 可运行

在 Java 中

// Import
import android.os.Handler;

// Use
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
     // do something after 1000ms
  }
}, 1000);

在科特林

// Import
import android.os.Handler;

// Use
val handler = Handler()
handler.postDelayed({
     // do something after 1000ms
}, 1000)

2. Kotlin 协程

// Import
import java.util.*
import kotlin.concurrent.schedule

// Use
Timer().schedule(1000){
    // do something after 1 second
}

3.RxJava

// Import
import io.reactivex.Completable
import java.util.concurrent.TimeUnit

// Use
Completable
     .timer(1, TimeUnit.SECONDS)
     .subscribeOn(Schedulers.io()) // where the work should be done
     .observeOn(AndroidSchedulers.mainThread()) // where the data stream should be delivered
     .subscribe({
          // do something after 1 second
     }, {
          // do something on error
     })

在这三者中,目前,RxJava 是在应用程序中实现多线程和处理大量数据流的方式。但是,如果您刚刚开始,最好先尝试基础知识。

参考


推荐阅读