首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin:如何在不冻结UI的情况下延迟Android中的代码

Kotlin:如何在不冻结UI的情况下延迟Android中的代码
EN

Stack Overflow用户
提问于 2019-01-24 22:18:54
回答 7查看 24.2K关注 0票数 19

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

代码语言:javascript
复制
Thread.sleep(1000)

但是它冻结了UI。

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

EN

回答 7

Stack Overflow用户

发布于 2019-01-25 01:33:25

出了什么问题

用法Thread.sleep(...)

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

OP (原始发帖者/提问者)澄清的

它冻结了UI,有人知道为什么会发生这种情况吗?

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

主线程,或者如果你在Android上做你的工作,它通常被称为UI线程

在Android平台上,默认情况下,应用程序在一个线程上运行。这个线程称为UI线程。之所以这样叫,是因为当用户与应用程序交互时,这个单独的线程会显示用户界面并侦听发生的事件。

如果不使用多线程API(如RunnableCoroutinesRxJava),您将自动在UI线程上调用Thread.sleep(1000),这就是为什么您会遇到这样的"UI冻结“体验,因为,其他UI Operations被阻止访问线程,因为您已经在线程上调用了挂起。

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

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

1.可运行的

在Java中

代码语言:javascript
复制
// Import
import android.os.Handler;

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

在Kotlin中

代码语言:javascript
复制
// Import
import android.os.Handler;

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

2. Kotlin协程

代码语言:javascript
复制
// Import
import java.util.*
import kotlin.concurrent.schedule

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

3. RxJava

代码语言:javascript
复制
// 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是在应用程序中进行多线程和处理大量数据流的最佳选择。但是,如果您刚刚开始,最好先尝试一下基础知识。

参考

票数 27
EN

Stack Overflow用户

发布于 2019-01-24 22:37:27

您可以使用处理程序对象https://developer.android.com/reference/android/os/Handler

代码语言:javascript
复制
val handler = Handler()
val runnable = Runnable {
    // code which will be delayed  
}

handler.postDelayed(runnable, 1000)

1000是以毫秒为单位的时间,您应该将其替换为您的值。

票数 8
EN

Stack Overflow用户

发布于 2019-01-24 22:35:41

如果您不想冻结UI,则需要在MainThread之外执行代码。

有很多方法可以做到这一点。下面是一些例子:

线程

代码语言:javascript
复制
Thread {
    Thread.sleep(1000)
    // Your code
}.start()

Rx

您需要https://github.com/ReactiveX/RxJava

代码语言:javascript
复制
Flowable.timer(1000, TimeUnit.MILLISECONDS)
    .subscribeOn(AndroidSchedulers.mainThread())
    .subscribe { 
        // Your code
    }

Kotlin协程

代码语言:javascript
复制
GlobalScope.launch { // launch new coroutine in background and continue
    delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
    println("World!") // print after delay
}

参考:https://kotlinlang.org/docs/reference/coroutines-overview.html

文档:

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54348728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档