mvvm dagger 2 ViewModelInjector - android

there, i need help, im a .NET developer, but now i want to try android.
i downloaded a project from here : https://github.com/gahfy/MVVMPosts
im having problems with the BaseViewModel.kt.
i know that DaggerViewMOdelInjector is created by dagger 2 with my interface ViewModelInjector, but it is not created and i cannot build the project, please help me !!
package net.gahfy.mvvmposts.base
import android.arch.lifecycle.ViewModel
import net.gahfy.mvvmposts.injection.component.DaggerViewModelInjector
import net.gahfy.mvvmposts.injection.component.ViewModelInjector
import net.gahfy.mvvmposts.injection.module.NetworkModule
import net.gahfy.mvvmposts.ui.post.PostListViewModel
import net.gahfy.mvvmposts.ui.post.PostViewModel
abstract class BaseViewModel:ViewModel(){
private val injector: ViewModelInjector = DaggerViewModelInjector
.builder()
.networkModule(NetworkModule)
.build()
init {
inject()
}
/**
* Injects the required dependencies
*/
private fun inject() {
when (this) {
is PostListViewModel -> injector.inject(this)
is PostViewModel -> injector.inject(this)
}
}
}

update like:-
implementation "com.google.dagger:dagger:$dagger2_version"
kapt "com.google.dagger:dagger-compiler:$dagger2_version"
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger2_version"
// compileOnly "org.glassfish:javax.annotation:3.1.1"

Related

Cannot resolve symbol DaggerAppComponent

There is my GitHub project - https://github.com/alekseytimoshchenko/MVVM_FLOW that I haven't used a lot of time and today I decided to check it out as a result I faced some compile/Gradle/build issues, so I needed to update some dependency and other things. Eventually looks like everything is ok, however, I got a compile
error: cannot find symbol
import com.example.krokosha.quizyourself.di.components.DaggerAppComponent;
This likely happens due to some specific dependencies or their version, I went through a few answers here on SO, but looks like everything is correct, but still, this class is not generated.
If it is suitable you are welcome to take a look at the project by the ref provided above, otherwise, I'll put some code here
There are my grale dependencies
...
//Dependency Injection
api "com.google.dagger:dagger:2.35.1"
annotationProcessor "com.google.dagger:dagger-compiler:2.28.3"
api "com.google.dagger:dagger-android:2.35.1"
api "com.google.dagger:dagger-android-support:2.28.3" // if you use the support libraries
annotationProcessor "com.google.dagger:dagger-android-processor:2.28.3"
...
and there is my class where I got an error:
package com.example.krokosha.quizyourself.di;
import android.content.Context;
import com.example.krokosha.quizyourself.di.components.AppComponent;
import com.example.krokosha.quizyourself.di.components.BaseComponent;
import com.example.krokosha.quizyourself.di.components.BaseComponentBuilder;
import com.example.krokosha.quizyourself.di.components.DaggerAppComponent;
import com.example.krokosha.quizyourself.di.moduls.AppModule;
import com.example.krokosha.quizyourself.di.moduls.BaseModule;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Provider;
public class ComponentsHolder
{
private final Context context;
#Inject
Map<Class<?>, Provider<BaseComponentBuilder>> builders;
private Map<Class<?>, BaseComponent> components;
private AppComponent appComponent;
public ComponentsHolder(Context context)
{
this.context = context;
}
public ComponentsHolder init()
{
appComponent = DaggerAppComponent.builder().appModule(new AppModule(context)).build();
appComponent.injectComponentsHolder(this);
components = new HashMap<>();
return this;
}
public BaseComponent getBaseComponent(Class<?> cls)
{
return getBaseComponent(cls, null);
}
public BaseComponent getBaseComponent(Class<?> cls, BaseModule module)
{
BaseComponent component = components.get(cls);
if (component == null)
{
BaseComponentBuilder builder = builders.get(cls).get();
if (module != null)
{
builder.module(module);
}
component = builder.build();
components.put(cls, component);
}
return component;
}
public void releaseBaseComponent(Class<?> cls)
{
components.put(cls, null);
}
}
What is a possible problem here?
DaggerAppComponent is the file Dagger generates as an implementation of your AppComponent interface. If DaggerAppComponent is not being generated, it usually means that Dagger has emitted an error that you can read further up in your compiler log. If you see one of those errors, please edit it into your question.
Also, note that you're mismatching your Dagger versions: your libraries are 2.35.1 but your annotation processor is 2.28.3. In some cases this mismatch can cause a compilation failure, though it's more typical for it to cause the generated DaggerAppComponent file to fail to compile within the generated code. (The generated code calls the dagger libraries at runtime, so if the versions don't match the generated code might call into a class or method that doesn't exist.) Because DaggerAppComponent is missing entirely, it's less likely that the version skew is the root cause of your error here, but in any case you should always have all your Dagger versions consistent: api/implementation/annotationProcessor and between dagger and dagger.android.

Why are some of these imports from the same library returning as unresolved references?

So I am currently trying to add a room database to an open-source project as part of my thesis, I grabbed the most recent example I could from android itself and modified it for Kotlin DSL, I used the same DAO and database structure but both have import errors. Normally this wouldn't be a problem to fix except I am getting errors from the same library in places which is why I had to ask this question in the first place. The main import problem is to do with androidx.room. Below is the kotlin file in question and after that, is the build.gradle.kts.
Just to add, android studio suggests I use persistence.room.runtime but from what I have tried and what I could find, this does not solve my problem either.
import androidx.room.Database //works
import androidx.room.Room // unresolved reference
import androidx.room.RoomDatabase // unresolved reference
#Database(entities = [GameDatabase::class], version = 1, exportSchema = false)
abstract class Database : RoomDatabase() {
abstract val DatabaseDAO: DatabaseDAO
companion object {
#Volatile
private var INSTANCE: Database? = null
fun getInstance(): Database {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
Database::class.java,
"game_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
Here is the module gradle build:
plugins {
//id("kotlin")
kotlin("kapt")
//kotlin("android")
//kotlin("android-extensions")
//id("kotlin-android")
//id("kotlin-android-extensions")
//id("androidx.navigation.safeargs")
}
java {
sourceCompatibility = JavaVersion.VERSION_1_6
}
tasks {
compileJava {
options.encoding = "UTF-8"
}
compileTestJava {
options.encoding = "UTF-8"
}
}
sourceSets {
main {
java.srcDir("src/")
}
}
// added
dependencies {
val room_version = "2.2.6"
val life_version = "2.2.0"
// Room and Lifecycle dependencies
implementation("androidx.room:room-runtime:$room_version")
kapt("androidx.room:room-compiler:$room_version")
//implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("androidx.lifecycle:lifecycle-extensions:$life_version")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$life_version")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$life_version")
implementation("androidx.lifecycle:lifecycle-common-java8:$life_version")
// adding Firebase dependencies
//implementation("android.arch.persistence.room:runtime:1.1.1")
//annotationProcessor("android.arch.persistence.room:compiler:2.2.6")
}
I am quite new to Kotlin DSL so it might be an obvious error but I also couldn't find anything like this in the area.
This is how I usually place the implementations:
//Room
implementation "androidx.room:room-runtime:2.2.6"
kapt "androidx.room:room-compiler:2.2.6"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:2.2.6"
Also, have you placed the kapt plugin? if not:
plugins {
id 'kotlin-android'
id 'kotlin-kapt'//this one
}
And, try to clean and rebuild the project.

how to fix subscribeOn (io.reactivex.Schedular) in Flowable cannot be applied to (rx.scheduler)

I am trying to do Room database operations using Rx java Flowable, but I think there is an issue with my imports but not sure what is the actual problem.
Error I get is
UserDao
import io.reactivex.Flowable
#Dao
interface UserDao {
#Query("SELECT * FROM user")
fun getAllUsers(): Flowable<List<User>>
#Insert
fun insertUser(user: User): Long
}
Presenter - where I am trying to access database is
import io.reactivex.Flowable;
import rx.schedulers.Schedulers;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
private void testingRoomDatabase() {
com.i6systems.in2plane.AppDatabase.User user = new com.i6systems.in2plane.AppDatabase.User(
1, "Test", "Room");
Long abcd = userDao.insertUser(user);
Flowable<List<com.i6systems.in2plane.AppDatabase.User>> users = userDao.getAllUsers();
getUsers().subscribeOn(Schedulers.computation()) // ***ISSUE IS HERE***
.observeOn(AndroidSchedulers.mainThread())
.subscribe(usersx -> {
});
}
private Long addUser(com.i6systems.in2plane.AppDatabase.User user) {
return userDao.insertUser(user);
}
private Flowable<List<com.i6systems.in2plane.AppDatabase.User>> getUsers () {
return userDao.getAllUsers();
}
Gradle imports
// RxAndroid and RxJava
implementation 'io.reactivex:rxandroid:1.2.0'
implementation 'io.reactivex:rxjava:1.1.10'
implementation('com.jakewharton.rxbinding:rxbinding:0.3.0') {
exclude group: 'com.android.support'
}
implementation "androidx.room:room-rxjava2:2.1.0"
implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
Your help is much appreciated
R

Testing RxWorker for WorkManager

I want to try out work manager for the first time. I am used to rxJava so I decided to implement my work manager using RxWorker. But the testing aspect is giving me headache.Basically, the work manager checks firebase to get latest changes to latest changes to particular document (This is not the best use case I know).But the problem is in the test returns without waiting for success or failure.It returns when the work manager is still running.
This is my work manager implementation
class MidiSyncWorker(context: Context, params: WorkerParameters) : RxWorker(context, params) {
override fun createWork(): Single<Result> {
return Injection.provideSharePrefsRepo.midiArchiveVersion()
.flatMapObservable { currentVersion ->
Injection.provideOnlineRepo.latestMidiArchive()
.filter { onlineMidi -> onlineMidi.version > currentVersion }
}.firstOrError()
.map { onlineMidi ->
val outputData = Data.Builder()
.putString(KEY_FIREBASE_ARCHIVE_PATH, onlineMidi.url)
Result.success(outputData.build()) }
}
.onErrorReturn { Result.failure() }
}
This is my test
fun midiSyncVersionCheck_success_onlineVersionDiffersFromLocalVersion() {
// create request
val request = OneTimeWorkRequestBuilder<MidiSyncWorker>()
.build()
wmRule.workManager.enqueue(request).result.get()
val workInfo = wmRule.workManager.getWorkInfoById(request.id).get(10, TimeUnit.SECONDS)
assertThat(workInfo.state, `is`(WorkInfo.State.SUCCEEDED))
}
I expected the test to wait until workmanager returns success or failure. But it returns while work manager is still running
java.lang.AssertionError:
Expected: is <SUCCEEDED>
but: was <RUNNING>
WorkManager makes available a couple of ways to test your Worker classes. You can find all the details on WorkManager Testing documentation page.
The original WorkManagerTestInitHelper only supports Worker classes, meanwhile, the newly introduce in (WorkManager v2.1.0-alpha01) TestListenableWorkerBuilder can be used to test both ListenableWorker classes and the other classes that derives from it (like CoroutineWorker and RxWorker.
In your particular case, you should be able to do:
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.work.ListenableWorker.Result
import androidx.work.testing.TestListenableWorkerBuilder
import org.hamcrest.CoreMatchers.`is`
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
#RunWith(JUnit4::class)
class MyWorkTest {
private lateinit var context: Context
#Before
fun setup() {
context = ApplicationProvider.getApplicationContext()
}
#Test
fun testMidiSyncWorker() {
// Get the ListenableWorker
val worker = TestListenableWorkerBuilder<MidiSyncWorker>(context).build()
// Start the work synchronously
val result = worker.startWork().get()
assertThat(result, `is`(Result.success()))
}
}
In this way you're calling synchrously your worker class.
In this case you need to use the as a test dependency in your build.gradle file:
def work_version = "2.1.0-alpha02"
androidTestImplementation "androidx.work:work-testing:$work_version"
You can find a similar, complete, sample (for a CoroutineWorker), on the Kotlin's coroutine Codelab.

How to import WorkManager class

I have this:
import android.arch.*;
public class ScrollingActivity extends AppCompatActivity {
private PeriodicWorkRequest notificationWorkSingle;
private WorkManager mWorkManager;
}
I love how not a single tutorial shows us which class to import
How to import PeriodicWorkRequest and WorkManager?
Of course:
import androidx.work.WorkManager;
import androidx.work.PeriodicWorkRequest;
and use this in build.gradle
dependencies {
implementation "android.arch.work:work-runtime:1.0.0-beta02"
}
and
dependencies {
classpath "android.arch.work:work-runtime:1.0.0-beta02"
}
A small addition to the answer by Alexander Mills:
Here's the link to the official docs on how to add Architecture Components to your project ->
Adding Components to your Project

Categories

Resources