假设有一个带有回调的接口:
interface SomeInterface {
fun doSomething(arg: String, callback: (Exception?, Long) -> Unit)
}
Run Code Online (Sandbox Code Playgroud)
我将其扩展为这样的挂起函数:
suspend fun SomeInterface.doSomething(arg: String): Long = suspendCoroutine { cont ->
this.doSomething(arg) { err, result ->
if (err == null) {
cont.resume(result)
} else {
cont.resumeWithException(err)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想在测试中模拟这个,但失败了。理想情况下,我想使用这样的东西:
@Test
fun checkService() {
runBlocking {
val myService = mock<SomeInterface>()
whenever(myService.doSomething(anyString())).thenReturn(1234L)
val result = myService.doSomething("")
assertEquals(result, 1234L)
}
}
Run Code Online (Sandbox Code Playgroud)
上述语法因模拟异常而失败,因为它期望回调的匹配器。
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
Run Code Online (Sandbox Code Playgroud)
我怎样才能模拟这样的挂起功能?如果无法使用类似的语法,我如何才能使用所需的参数进行模拟回调,以便在整个代码中使用的挂起变体在测试期间返回所需的结果?
更新:当它是一个扩展功能时,它似乎是不可能的。根据Marko Topolnik的评论,我认为这是因为扩展只是一个静态函数,它超出了 …
当我尝试编译用Kotlin编写的Android应用程序时,我收到以下编译错误,并且我的构建失败:
w: -Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
compiler-errors gradle kotlin android-studio kotlinx.coroutines
在阅读了CoroutineScope的介绍和javadoc后,我仍然有点混淆了背后的想法CoroutineScope是什么.
文档的第一句"定义新协程的范围".我不清楚:为什么我的协同程序需要一个范围?
另外,为什么单独的协同构建器被弃用?为什么这样做更好:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
Run Code Online (Sandbox Code Playgroud)
代替
fun produceSquares(): ReceiveChannel<Int> = produce { //no longer an extension function
for (x in 1..5) send(x * x)
}
Run Code Online (Sandbox Code Playgroud) 我有一个android服务,可在服务器在线时启动并与服务器同步不同类型的数据。我是Kotlin协程的新手,我正在尝试完成以下任务:
fun syncData{
//Job1 make retrofit call to server
//Job2 make retrofit call to server after job1 is done.
//Job3 make retrofit call to server after job 2 is done and so on.
//After all jobs are done I'll stop service.
}
Run Code Online (Sandbox Code Playgroud)
我在关注这篇文章: Kotlin Coroutines在Android中的正确方法
这给我带来了这个解决方案:
fun syncData() = async(CommonPool){
try{
val sync1 = async(CommonPool){
job1.sync()
}
val sync2 = async(CommonPool){
job2.sync()
}
val sync3 = async(CommonPool){
job3.sync()
}
val sync4 = async(CommonPool){
job4.sync()
}
job1.await()
job2.await()
job3.await()
job4.await()
}catch …Run Code Online (Sandbox Code Playgroud) 如何从暂停功能启动协程并使其使用当前的示波器?(这样,直到启动的协程也结束,作用域才结束)
我想写类似下面的内容–
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
go()
}
suspend fun go() {
launch {
println("go!")
}
}
Run Code Online (Sandbox Code Playgroud)
但这有一个语法错误:“未解决的参考:启动”。似乎launch必须以下列方式之一运行-
GlobalScope.launch {
println("Go!")
}
Run Code Online (Sandbox Code Playgroud)
要么
runBlocking {
launch {
println("Go!")
}
}
Run Code Online (Sandbox Code Playgroud)
要么
withContext(Dispatchers.Default) {
launch {
println("Go!")
}
}
Run Code Online (Sandbox Code Playgroud)
要么
coroutineScope {
launch {
println("Go!")
}
}
Run Code Online (Sandbox Code Playgroud)
这些替代方法都不能满足我的需求。代码要么“阻塞”而不是“产生”,要么产生,但是父作用域在父作用域本身结束之前不会等待其完成。
我需要它在当前的父协程作用域中“生成”(启动),并且该父作用域应等待所生成的协程完成,然后结束自身。
我希望a launch内的简单内容suspend fun有效并使用其父范围。
我正在使用Kotlin 1.3和cotlinx-coroutines-core:1.0.1。
因此,我最近开始使用协同程序进行实验,我从Rxjava2切换到协同程序,我还没有掌握它但仍然,我遇到了一个需要观察我的数据库更改并更新对应的UI的情况.
RxJava曾经为我提供Flowables,Completeable等,使用它我可以观察到Db的变化.
abstract fun insert(data: SomeData): Long
@Query("SELECT * FROM somedata_table")
abstract fun getData(): Flowable<List<SomeData>>
Run Code Online (Sandbox Code Playgroud)
所以现在这里我曾经订阅了getData并且总是习惯于观察变化
现在输入coroutines,我使用带有延迟结果的暂停函数来返回我的响应
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(data: SomeData): Long
@Query("SELECT * FROM somedata_table")
abstract fun getData(): List<SomeData>
Run Code Online (Sandbox Code Playgroud)
suspend fun getAllSomeData():Deferred<List<SomeData>>{
return GlobalScope.async (context= coroutineContext){
database.myDao().getData()
}
}
Run Code Online (Sandbox Code Playgroud)
现在我无法听取更新,协程中的频道可能是正确的答案吗?但我不确定如何使用Room.
我有一个Sequence(来自File.walkTopDown),我需要在每个上运行一个长时间运行的操作.我想使用Kotlin最佳实践/协同程序,但我要么没有并行性,要么太多并行性并且遇到"太多打开文件"IO错误.
File("/Users/me/Pictures/").walkTopDown()
.onFail { file, ex -> println("ERROR: $file caused $ex") }
.filter { ... only big images... }
.map { file ->
async { // I *think* I want async and not "launch"...
ImageProcessor.fromFile(file)
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎没有并行运行,我的多核CPU永远不会超过1 CPU的价值.是否有协同程序运行"NumberOfCores并行操作"值得延期的工作?
我使用Kotlin协同程序查看多线程,它首先创建所有作业,然后加入它们,但这意味着在重处理连接步骤之前完成序列/文件树步骤,这似乎......如果!将其拆分为收集和处理步骤意味着收集可以在处理之前运行.
val jobs = ... the Sequence above...
.toSet()
println("Found ${jobs.size}")
jobs.forEach { it.await() }
Run Code Online (Sandbox Code Playgroud) parallel-processing multithreading kotlin kotlinx.coroutines
Firebase匿名登录返回任务(基本上是Google承诺实施):
val task:Task<AuthResult> = FirebaseAuth.getInstance().signInAnonymously()
Run Code Online (Sandbox Code Playgroud)
如何创建一个signInAnonymous包装器:
这是一个suspend功能,等待task完成
suspend fun signInAnonymous(): Unit它返回一个Deferred对象,异步传递结果
fun signInAnonymous() : Deferred我kotlinx-coroutines-android:1.0.0-RC1在我的Android项目中使用Kotlin 1.3 EAP .我的开发构建成功,应用程序运行正常.但是,当我Generate Signed APK,应用程序仍然构建和运行,但随后崩溃
java.lang.IllegalStateException:Main缺少调度程序的模块.添加提供Main调度程序的依赖项,例如'kotlinx-coroutines-android'
由于dev构建运行良好,显然gradle文件中没有遗漏.我有这些设置:
项目build.gradle:
buildscript {
ext.kotlin_version = '1.3.0-rc-190'
....
Run Code Online (Sandbox Code Playgroud)
模块build.gradle:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0-RC1'
Run Code Online (Sandbox Code Playgroud)
随着时间的推移,相同的应用程序已经与许多不同版本的实验协同程序一起运行,这是我第一次遇到这个问题.我怀疑EAP工件中有一些临时问题.
我有什么办法让这项工作成功?
我想使用 Kotlin(v1.3.0)协程和 java.nio.channels。SocketChannel (NIO) 来替代connectAndroid 中的Socket (阻塞 IO)。因为这可以节省很多线程。
下面的代码因为job.await()在 Kotlin 中挂起函数而无法运行,它只能在 Ktolin 协程块中调用。喜欢launch{..},async{..}。
// this function will be called by Java Code
fun connect(address: InetSocketAddress, connectTimeout: Int): SocketChannel {
// Start a new connection
// Create a non-blocking socket channel
val socketChannel = SocketChannel.open()
socketChannel.configureBlocking(false)
// async calls NIO connect function
val job = GlobalScope.async(oneThreadCtx) {
aConnect(socketChannel, address)
}
// I what to suspend(NOT block) current Java Thread, until …Run Code Online (Sandbox Code Playgroud)