Room database.withTransaction { } block not Resolved - android

I am following this tutorial about RemoteMediator and everything is fine until I run into a weird error when using database.withTransaction{} to allow database operations.
Unfortunately, the IDE doesn't seem (or is refusing) to recognize this very genuine and
legit block. I have checked that I defined ROOM Database abstract class correctly and declared these ROOM and Paging 3 libs in build.gradle(app) file.
// Room
implementation "androidx.room:room-runtime:2.4.3"
kapt "androidx.room:room-compiler:2.4.3"
// Room-paging artifact
implementation 'androidx.room:room-paging:2.4.3'
// Paging 3.0
implementation 'androidx.paging:paging-compose:1.0.0-alpha16'
So I decided to ignore the error and went ahead to call a dao function inside the withTransaction{} block but I get Suspension functions can be called only within a coroutine body.
This is a bit confusing since RemoteMediator's load() override function is already a suspend function.
Anyone with insights on this issue please help as I don't seem to be getting anywhere around this.

Thanks to #ianhanniballake day-saving comment above, if you run into this situation just change the room-runtime flavor from:
implementation "androidx.room:room-runtime:2.4.3"
kapt "androidx.room:room-compiler:2.4.3"
to room-ktx flavor:
implementation "androidx.room:room-ktx:2.4.3"
kapt "androidx.room:room-compiler:2.4.3"
As per Developers Docs ktx-libs provide Kotlin Extensions and Coroutines support which is exactly what database.withTransaction{} block is - it is an extension function on RoomDatabase as shown on this line from the source code.
public suspend fun <R> RoomDatabase.withTransaction(block: suspend () -> R): R {
Android KTX is a set of Kotlin extensions that are included with
Android Jetpack and other Android libraries. KTX extensions provide
concise, idiomatic Kotlin to Jetpack, Android platform, and other
APIs. To do so, these extensions leverage several Kotlin language
features, including the following:
Extension functions
Extension properties
Lambdas
Named parameters
Parameter default values
Coroutines

Related

Koin - Ensure that all "by inject" are valid

I work on an Android project using multiple Project Flavors, and we use Koin to inject the appropriate dependencies based on the current flavor.
We already use the checkModules Gradle task (described here : https://start.insert-koin.io/#/getting-started/testing?id=checking-your-modules) in order to ensure that our dependency tree is valid.
However, it seems that there is a use case missing.
Let's say I want to inject an InterfaceA in my Activity. I would write the following code :
class MyActivity : Activity() {
private val interfaceA_Impl: InterfaceA by inject()
...
}
Koin requires the implementation of InterfaceA to be provided in a module, as such :
val myModule = module {
single<InterfaceA> { MyInterfaceImpl() }
}
In my project, each implementation is "flavor-specific".
My question is :
Is there a way to ensure that ALL by inject targets are valid ? In other words, to ensure that all interfaces that I am trying to inject have valid implementations ? Currently, if an implementation is forgotten, the app crashes during runtime, and I would like to know about it sooner (maybe during unit tests, at the same time checkModules is ran ?)
Thanks a lot !

Can't use liveData or viewModelScope.launch

I'm trying to use these two builders for coroutines in my app, but in my ViewModel I can't import them or they do not pop up.
These are my dependencies:
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0-rc02"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2'
and in my ViewModel
class MainViewModel(): ViewModel() {
init{
viewModelScope ----> does not work , marked in red
val data = liveData {} ----> does not work, marked in red
}
}
I rebuilt, cleaned, and restarted with invalidating cache, but I can't use them
Add the ViewModel ktx lib:
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx$lifecycle_version"
Available after AndroidX lifecycle v2.1.0
for liveData:
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$livedata_version"
for viewModelScope:
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
The above additions to build.gradle with cache invalidation and rebuild still were not sufficient to resolve the issue for me (Android Studio Bumblebee | 2021.1.1 Patch 2). Only when I wrote this. I could choose viewModelScope from the pulldown, with automatic import insertion.

Unresolved reference: viewModelScope - Android KTX

I'm trying to use the new viewModelScope() function provided by the new android ktx library.
In the gradle file, I've added:
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0'
implementation 'androidx.core:core-ktx:1.0.2'
but when I tied to access the viewModelScope(), I got Unresolved reference: viewModelScope error:
class MainViewModel(application: Application): AndroidViewModel(application) {
fun fetchData(){
viewModelScope.launch{
}
}
}
I don't understand what the problem is. Any idea? Thanks.
Check the release notes https://developer.android.com/jetpack/androidx/releases/lifecycle#declaring_dependencies
viewModelScope is available from v2.1.x
So you need to bump your version in your gradle file.
I have use in my project 2.1.0-beta01:
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0-beta01"
This is less version then released on official site.
However, I use it because new version 2.2.0-alpha01 still has the Unresolved reference: viewModelScope - Android KTX error.

How to get lifecycle.coroutineScope with new androidx.lifecycle:*:2.2.0-alpha01

On 7th May, 2019 androidx.lifecycle:*:2.2.0-alpha01 was released announcing:
This release adds new features that adds support for Kotlin coroutines for Lifecycle and LiveData. Detailed documentation on them can be found here.
On documentation it's mentioned that I can get the LifecycleScope:
either via lifecycle.coroutineScope or lifecycleOwner.lifecycleScope properties
But it seems that I'm not able to find none of them. My current dependencises are:
def lifecycle_ver = "2.2.0-alpha01"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_ver"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_ver"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_ver"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1'
What may be the cause and how do get these apis?
I actually spent a couple hours trying to figure this out myself and it turns out it is in a new package that only exists as of the alpha. Add this and you should be good to go.
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_ver"
The accepted answers is working, but I'm misused for the first time, so I'm trying to make it clear, the current version of lifecycle is "2.1.0" and lifecycleScope, and ViewModelScope is not available in this version, to get them use
For ViewModelScope,
use androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0-beta01 or higher.
For LifecycleScope,
use androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha01 or higher.
at this time 2.4.1 is available.
I've just added this two lines of code to my build.gradle (App) and that worked like a charm. I can import lifecycleScope without any problems.
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'

How to use kotlin.system with Kotlin Native?

I'd like to use system functions like getTimeMillis() which should be a part of kotlin.system: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.system/index.html
But the compiler says such module cannot be imported. The gradle configuration is like this (kotlin multiplatform project):
commonMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:1.3.10"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.10.0"
implementation "io.ktor:ktor-client:1.0.0"
implementation "io.ktor:ktor-client-logging:1.1.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.0"
}
Also I cannot find any example of usage or this module.
getTimeMillis() is only available for JVM and Native not for Common and JS.
If you but the call to getTimeMillis() in the source directory of the Native module the compiler can find the function.
If you need the call to be in Common you have to implement a Common wrapper function on your own and implement the wrapper on each platform yourself.
In order to do this create a stub function and a function which uses it in your common module . For example:
expect fun getSystemTimeInMillis(): Long
fun printSystemTimeMillis() {
println("System time in millis: ${getSystemTimeInMillis()}")
}
Then implement that function your platform specific modules. For example in a JVM module like:
actual fun getSystemTimeInMillis() = System.currentTimeMillis()
Or in a native module like:
actual fun getSystemTimeInMillis() = getTimeMillis()
See also: https://github.com/eggeral/kotlin-native-system-package

Categories

Resources