我试图调试我的协程,但放置在挂起函数中的断点不起作用。请帮助我理解为什么。
使用 Android Studio。
好的,我从 viewModelScope 启动了一个协程:
viewModelScope.launch(IO) {
when(val result = interactor.getAllWords()){...}
}
Run Code Online (Sandbox Code Playgroud)
在getAllWords()我写道:
override suspend fun getAllWords(): WordResult {
val words = mutableListOf<Word>()
when (val wordsResult = getAllWordsWithoutFiltersApplying()) {}
...
return getWordsWithSelectedPattern()
Run Code Online (Sandbox Code Playgroud)
我有两个挂起功能:getAllWordsWithoutFiltersApplying()和getWordsWithSelectedPattern()。我对它们都有一个断点,但它们没有在调试模式下触发。
同时,线 val words = mutableListOf<Word>(),当我将断点放在它的行上正在触发。
而且,如果我将一些日志内容放入“untracing”功能中,它们将起作用。我这么说是为了说明,暂停功能有效。断点不是。
我该怎么做才能调试它们?
*截图已添加。看左边有一排图标。为什么我的线路不可用?
我正在使用kotlin coroutines进行网络请求,使用扩展方法在这样的改造中调用类
public suspend fun <T : Any> Call<T>.await(): T {
return suspendCancellableCoroutine { continuation ->
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>?, response: Response<T?>) {
if (response.isSuccessful) {
val body = response.body()
if (body == null) {
continuation.resumeWithException(
NullPointerException("Response body is null")
)
} else {
continuation.resume(body)
}
} else {
continuation.resumeWithException(HttpException(response))
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
// Don't bother with resuming the continuation if it is already cancelled.
if (continuation.isCancelled) return
continuation.resumeWithException(t)
} …Run Code Online (Sandbox Code Playgroud) 当我尝试将 Dao 更改为新的FlowApi 时,出现编译错误,指出
Not sure how to convert a Cursor to this method's return type
public abstract kotlinx.coroutines.flow.Flow<java.util.List<com.ezek.ezign.model.ECampaign>> readCampaigns();
Run Code Online (Sandbox Code Playgroud)
道是
@Dao
interface CampaignDao {
@Query("SELECT * FROM campaign ORDER BY timeStamp ASC")
fun readCampaigns(): Flow<List<ECampaign>>
@Query("SELECT * FROM campaign WHERE id = :campaignId")
fun readCampaign(campaignId: Int): Flow<ECampaign>
}
Run Code Online (Sandbox Code Playgroud)
和依赖项是
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2'
implementation "android.arch.persistence.room:runtime:$rootProject.ext.room_version"
kapt "android.arch.persistence.room:compiler:$rootProject.ext.room_version"
//room_version = "2.1.0"
Run Code Online (Sandbox Code Playgroud)
我已经尝试过两者List和ArrayList,但没有运气。
提前致谢。
Kotlin corutines是有限状态机和一些任务运行器的糖(例如,默认的ForkJoinPool).https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#implementation-details
换句话说,java/kotlin运行时中还没有运行时协同程序(但这可以随http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html而改变).Kotlin协程只是连续执行的任务,它们是逐个执行的.每个任务都可以在线程池的任何线程中执行.
Go运行时支持"协同程序".但是goroutines并不是真正的协同程序.Goroutines不允许在程序中设置屈服点.此外,Go不允许设置自定义线程池.您只能在默认池中设置线程大小.
kotlin协同程序和goroutine之间的第一个区别是Go运行时管理此时正在运行的协同程序.当goroutine在某些IO操作(或同步原语)被阻塞时,请选择下一个Job来执行它.在JVM中,没有这种术语的智能工作转换.
因此,Go可以廉价地改变当前正在运行的工作.Go只需改变一些注册表https://groups.google.com/forum/#!msg/golang-nuts/j51G7ieoKh4/wxNaKkFEfvcJ.但也有人说,JVM可以使用堆栈线程而不是使用寄存器.因此根本没有保存和加载寄存器.
kotlin协程和goroutines之间的第二个区别是协同程序的类型.Kotlin协同程序是无堆栈协程.Goroutines是堆栈协程.Kotlin协程的所有状态都存储在Kotlin上下文中,该上下文存储在堆中.Goroutines状态存储在寄存器和线程堆栈中.
我想知道,哪些协程(goroutines和kotlin协程)在IO绑定任务中更快?CPU绑定任务?内存消耗怎么样?
我正在尝试在我的项目中实现 NetworkBoundResource 类,这就是我正在尝试的。一切正常,获得响应,缓存,但是当我在 flowBuilder 中发出值时,它崩溃并显示此错误。
我收到错误:
Emission from another coroutine is detected.
Child of ProducerCoroutine{Active}@df26eb9, expected child of FlowCoroutine{Active}@a0bb2fe.
FlowCollector is not thread-safe and concurrent emissions are prohibited.
To mitigate this restriction please use 'channelFlow' builder instead of 'flow')' has been detected.
Emissions from 'catch' blocks are prohibited in order to avoid unspecified behaviour, 'Flow.catch' operator can be used instead.
For a more detailed explanation, please refer to Flow documentation.
Run Code Online (Sandbox Code Playgroud)
网络绑定资源类:
abstract class NetworkBoundResource<ResultType, RequestType> {
fun invoke(): Flow<Resource<ResultType>> = …Run Code Online (Sandbox Code Playgroud) 我有这样的课
class SomeClass {
fun someFun() {
// ... Some synchronous code
async {
suspendfun()
}
}
private suspend fun suspendFun() {
dependency.otherFun().await()
// ... other code
}
}
Run Code Online (Sandbox Code Playgroud)
我想进行单元测试,someFun()所以我编写了一个单元测试,如下所示:
@Test
fun testSomeFun() {
runBlocking {
someClass.someFun()
}
// ... verifies & asserts
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用,因为runBlocking实际上不会阻止执行,直到runBlocking内的所有内容都完成.如果我suspendFun()直接在里面测试runBlocking它按预期工作,但我希望能够一起测试someFun().
有关如何使用同步和异步代码测试函数的任何线索?
在阅读了这个问题如何处理异常和这个2019 年的中型Android 网络 - 使用 Kotlin 的协程改造后,我创建了我的解决方案,其中包括BaseService能够进行改造调用并将结果和异常转发到“链”中:
应用程序接口
@GET("...")
suspend fun fetchMyObject(): Response<List<MyObject>>
Run Code Online (Sandbox Code Playgroud)
基本服务
protected suspend fun <T : Any> apiCall(call: suspend () -> Response<T>): Result<T> {
val response: Response<T>
try {
response = call.invoke()
} catch (t: Throwable) {
return Result.Error(mapNetworkThrowable(t))
}
if (!response.isSuccessful) {
return Result.Error...
}
return Result.Success(response.body()!!)
}
Run Code Online (Sandbox Code Playgroud)
儿童服务
suspend fun fetchMyObject(): Result<List<MyObject>> {
return apiCall(call = { api.fetchMyObject() })
}
Run Code Online (Sandbox Code Playgroud)
回购
suspend fun myObjectList(): List<MyObject> {
return …Run Code Online (Sandbox Code Playgroud) android kotlin kotlin-android-extensions retrofit2 kotlin-coroutines
在上一次 Google I/O 大会上,Jose Alcerreca 和 Yigit Boyar告诉我们,我们不应再使用 LiveData 来获取数据。现在我们应该使用挂起函数进行一次性提取并使用 Kotlin 的 Flow 创建数据流。我同意协程非常适合一次性获取或其他 CRUD 操作,例如插入等。但是在我需要数据流的情况下,我不明白 Flow 给我带来了什么优势。在我看来,LiveData 也在做同样的事情。
流程示例:
视图模型
val items = repository.fetchItems().asLiveData()
Run Code Online (Sandbox Code Playgroud)
存储库
fun fetchItems() = itemDao.getItems()
Run Code Online (Sandbox Code Playgroud)
道
@Query("SELECT * FROM item")
fun getItems(): Flow<List<Item>>
Run Code Online (Sandbox Code Playgroud)
LiveData 示例:
视图模型
val items = repository.fetchItems()
Run Code Online (Sandbox Code Playgroud)
存储库
fun fetchItems() = itemDao.getItems()
Run Code Online (Sandbox Code Playgroud)
道
@Query("SELECT * FROM item")
fun getItems(): LiveData<List<Item>>
Run Code Online (Sandbox Code Playgroud)
我还想看到一些使用协程和 Flow 来处理 Room 或 Retrofit 的项目示例。我只找到了一个 Google 的ToDo 示例,其中协程用于一次性获取,然后在更改时手动重新获取数据。
android kotlin android-livedata kotlin-coroutines kotlinx.coroutines.flow
我正在使用 Kotlin,现在 android studio 建议我添加
这是一个微妙的 API,使用时需要小心。确保您完全阅读并理解标记为敏感 API 的声明文档。
当我点击
add @DelicateCoroutinesApi annotation to function
Run Code Online (Sandbox Code Playgroud)
它添加了 @DelicateCoroutinesApi
这样的东西
@DelicateCoroutinesApi
fun getAmount(activity: LoginActivity, user:FirebaseUser){
mFireStore.collection(Constants.AMOUNT).document(user.uid).get().
addOnSuccessListener { d ->
activity.amountGetSuccess( d, user)
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用协程时,它建议我看另一个例子
@DelicateCoroutinesApi
private fun playsound() {
GlobalScope.launch {
withTimeout(10L) {
// play sound
val mPlayerPress = MediaPlayer.create(this, R.raw.button_press)
mPlayerPress.start()
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么这个@DelicateCoroutinesApi @DelicateCoroutinesApi 的工作是什么
最近我更新了我ViewModel的使用新的viewModelScope. 从它的实现来看,我看到它Dispatchers.Main.immediate被设置CoroutineDispatcher为viewModelScope.
所以当打印当前Thread在viewModelScope.launch它给Thread[main,5,main]
但这是我的问题。尽管它在主线程中运行,但以下代码对我执行网络调用有效。
viewModelScope.launch {
userRepo.login(email, password)
}
Run Code Online (Sandbox Code Playgroud)
这userRepo.login(email, password)是suspend函数,它调用Retrofit suspend函数。
那么这是如何工作的,如果我的当前线程是主线程?
kotlin ×9
android ×7
coroutine ×2
retrofit2 ×2
android-room ×1
async-await ×1
debugging ×1
go ×1
goroutine ×1
retrofit ×1
unit-testing ×1