标签: kotlinx.coroutines

单位测试Kotlin协程延迟

我正在尝试对使用的Kotlin协程进行单元测试delay().对于单元测试我不关心delay(),它只是减慢测试速度.我想以某种方式运行测试,这种方式在delay()调用时实际上并没有延迟.

我尝试使用委托给CommonPool的自定义上下文来运行协同程序:

class TestUiContext : CoroutineDispatcher(), Delay {
    suspend override fun delay(time: Long, unit: TimeUnit) {
        // I'd like it to call this
    }

    override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) {
        // but instead it calls this
    }

    override fun dispatch(context: CoroutineContext, block: Runnable) {
        CommonPool.dispatch(context, block)
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望我可以从我的上下文delay()方法返回,但是它调用我的scheduleResumeAfterDelay()方法,我不知道如何将它委托给默认的调度程序.

unit-testing kotlin kotlinx.coroutines

27
推荐指数
4
解决办法
2815
查看次数

缺少主调度程序的模块

我正在尝试对我的本地数据库进行后台调用,并使用协同程序使用结果更新UI.这是我的相关代码:

import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.Dispatchers.IO
import kotlinx.coroutines.experimental.Dispatchers.Main
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.experimental.suspendCoroutine

class WarehousesViewModel(private val simRepository: SimRepository)
: BaseReactViewModel<WarehousesViewData>(), CoroutineScope {

private val job = Job()

override val coroutineContext: CoroutineContext
    get() = job + Main

override val initialViewData = WarehousesViewData(emptyList())

override fun onActiveView() {
    launch {
        val warehouses = async(IO) { loadWarehouses() }.await()
        updateViewData(viewData.value.copy(items = warehouses))
    }
}

private suspend fun loadWarehouses(): List<Warehouse> =
    suspendCoroutine {continuation ->
        simRepository.getWarehouses(object : SimDataSource.LoadWarehousesCallback {
            override fun onWarehousesLoaded(warehouses: List<Warehouse>) {
                Timber.d("Loaded warehouses")
                continuation.resume(warehouses)
            }

            override …
Run Code Online (Sandbox Code Playgroud)

android coroutine kotlin kotlinx.coroutines

24
推荐指数
4
解决办法
8587
查看次数

在改造验证器中使用协程

我正在尝试使用协程在改造中实现 JWT 令牌身份验证和刷新令牌。令牌存储在 Room 数据库中。我应该如何实现 await 调用?

目前我正在使用 runBlocking {...} 调用来等待异步本地/远程响应

例子:

client.addInterceptor {
        val accessToken = runBlocking { tokenRepository.getActiveToken() }?.access_token ?: "-"
        val request = it.request()
            .newBuilder()
            .addHeader("Authorization", "Bearer $accessToken")
            .build()
        return@addInterceptor it.proceed(request)
    }
Run Code Online (Sandbox Code Playgroud)

我想遵循的是传统模式:

launch {
    withContext(IO){...}
}
Run Code Online (Sandbox Code Playgroud)

我该怎么办?

android retrofit2 kotlinx.coroutines

15
推荐指数
1
解决办法
3141
查看次数

kotlin 协程抛出 java.lang.IllegalStateException:已经恢复,但得到了值位置

总的来说,我对 Kotlin 协程和 Android 开发很陌生。在尝试了解它是如何工作的时,我遇到了一个似乎无法解决的错误。

从基本活动中,我尝试连接到 googleApiClient。权限没问题。我希望使用 kotlin 协程以直接方式从 LocationManager 获取位置更新,以便稍后使用此 Location 对象。我第一次在模拟器中改变我的位置时它工作正常,第二次我改变我的位置时,它崩溃了,异常如下:

FATAL EXCEPTION: main
    Process: com.link_value.eventlv, PID: 32404
    java.lang.IllegalStateException: Already resumed, but got value Location[gps 48.783000,2.516180 acc=20 et=+59m16s372ms alt=0.0 {Bundle[mParcelledData.dataSize=40]}]
    at kotlinx.coroutines.experimental.AbstractContinuation.resumeImpl(AbstractContinuation.kt:79)
    at kotlinx.coroutines.experimental.AbstractContinuation.resume(AbstractContinuation.kt:72)
    at com.link_value.eventlv.View.Create.NewEventLvActivity$await$2$1.onLocationChanged(NewEventLvActivity.kt:100)
    at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:297)
    at android.location.LocationManager$ListenerTransport.-wrap0(LocationManager.java)
    at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:242)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:154)
     at android.app.ActivityThread.main(ActivityThread.java:6077)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)



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

    askForUserLocation()
    val locationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    val presenter = CreateEventPresenterImpl(this@NewEventLvActivity)

    googleApiClient = GoogleApiClient.Builder(this@NewEventLvActivity)
            .enableAutoManage(this /* …
Run Code Online (Sandbox Code Playgroud)

android locationmanager kotlin kotlinx.coroutines

14
推荐指数
3
解决办法
9120
查看次数

Kotlin 协程单元测试错误:线程“main @coroutine#1 @coroutine#2”中的异常 java.lang.NullPointerException

我正在尝试对我用 Kotlin 协程制作的演示器进行单元测试,这也是我第一次使用 Mockito

每当我尝试运行单元测试时,我第一次尝试在协程中对我的视图执行任何操作时都会收到以下错误

Exception in thread "main @coroutine#1 @coroutine#2" java.lang.NullPointerException
    at .signin.SignInPresenter$subscribe$1.doResume(SignInPresenter.kt:45)
    at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:54)
    at kotlinx.coroutines.experimental.DispatchedKt.resumeCancellable(Dispatched.kt:208)
    at kotlinx.coroutines.experimental.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:35)
    at kotlinx.coroutines.experimental.CoroutineStart.invoke(CoroutineStart.kt:111)
    at kotlinx.coroutines.experimental.AbstractCoroutine.start(AbstractCoroutine.kt:161)
    at kotlinx.coroutines.experimental.BuildersKt.launch(Builders.kt:68)
    at kotlinx.coroutines.experimental.BuildersKt.launch$default(Builders.kt:61)
    at .signin.SignInPresenter.subscribe(SignInPresenter.kt:42)
Run Code Online (Sandbox Code Playgroud)

这是我的演示者的相关部分,错误中引用的行是 view.showSigninPanel

class SignInPresenter(
    private val view: SignInContract.View,
    private val userRepo: ParseAuthController,
    private val contextPool: CoroutineContextProvider
) : SignInContract.Presenter {

    private val coroutineJobs: MutableList<Job> = mutableListOf()

    override fun subscribe() {
        view.loadBackgroundImage()
        view.setUpSignInPanel()
        view.setUpKeyboardListener()

        coroutineJobs.add(launch(contextPool.Main) {
            if (!userRepo.isAuthenticated()) {
                view.showSignInPanel()
                subscribeToLoginValidation()
                subscribeToPaswordEmailValidation()
            } else {
                view.launchMainActivity()
            }
        })
    }
Run Code Online (Sandbox Code Playgroud)

呼叫userRepo.isAuthenticated() …

android unit-testing mockito kotlin kotlinx.coroutines

14
推荐指数
1
解决办法
5101
查看次数

挂起函数“ callGetApi”只能从协程或其他挂起函数中调用

我正在从onCreate(...)调用暂停的函数

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    ...
    callGetApi()
}
Run Code Online (Sandbox Code Playgroud)

暂停功能为:

suspend fun callGetApi() {....}
Run Code Online (Sandbox Code Playgroud)

但是错误显示挂起函数“ callGetApi”应仅从协程或另一个挂起函数调用

android coroutine kotlin kotlinx.coroutines

13
推荐指数
3
解决办法
5629
查看次数

NetworkOnMainThreadException 对于协程中的网络调用是否有效?

我正在用 Kotlin for Android 组装一个简单的演示应用程序,它使用 Jsoup 检索网页的标题。我正在使用Dispatchers.Main作为上下文进行网络调用。

我的协同程序的理解是,如果我叫launchDispatchers.Main在主线程运行,但暂停执行,从而不会阻塞线程。

我的理解android.os.NetworkOnMainThreadException是它存在是因为网络操作很重,在主线程上运行时会阻塞它。

所以我的问题是,鉴于协程不会阻塞它运行的线程,它NetworkOnMainThreadException真的有效吗?下面是一些示例代码,它在 处抛出给定的异常Jsoup.connect(url).get()

class MainActivity : AppCompatActivity() {
    val job = Job()

    val mainScope = CoroutineScope(Dispatchers.Main + job)

    // called from onCreate()
    private fun printTitle() {
        mainScope.launch {
            val url ="https://kotlinlang.org"
            val document = Jsoup.connect(url).get()
            Log.d("MainActivity", document.title())
            // ... update UI with title
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以简单地使用Dispatchers.IO上下文运行它并将这个结果提供给主/UI 线程,但这似乎避开了协程的一些效用。

作为参考,我使用的是 Kotlin 1.3。

android kotlin kotlinx.coroutines

12
推荐指数
2
解决办法
4369
查看次数

Kotlin Coroutines具有回归价值

我想创建一个具有返回值的协程方法.

例如)

fun funA() = async(CommonPool) {
    return 1
}

fun funB() = async(CommonPool) {
    return 2
}

fun sum() {
    launch {
        val total = funA().await() + funB().await()
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想要求总和方法,我该怎么办?

喜欢,

fun sum(): Int {
    launch {
        val total = funA().await() + funB().await()
    }   

    return total
}
Run Code Online (Sandbox Code Playgroud)

kotlin kotlinx.coroutines

11
推荐指数
6
解决办法
1万
查看次数

Kotlin Android辩护

有没有任何奇特的方法来实现debounceKotlin Android的逻辑?

我没有在项目中使用Rx.

Java中有一种方法,但它对我来说太大了.

android kotlin kotlin-extension kotlin-android-extensions kotlinx.coroutines

11
推荐指数
9
解决办法
5831
查看次数

使用Kotlin 1.3迁移到Android中的Kotlin协同程序

我应该在我的build.gradle文件中更改或导入类以在我的Android项目中使用Kotlin 1.3使用稳定的协程函数?

关于我的协同程序的碎片 build.gradle

implementation "org.jetbrains.kotlin:kotlin-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlin:kotlin-coroutines-android:$coroutines_version"

当然我使用的是Android Studio 3.3 Preview

android kotlin kotlinx.coroutines

11
推荐指数
2
解决办法
6747
查看次数