I am using clean architecture in my app, and due-to module testing I have to keep module logic inside modules. However all examples of constructions of RoomDatabase forcing to keep all DAO's inside RoomDatabase child class.
Is it possible to split RoomDatabase creation and DAO attachment place into two different modules(in case if one of them depends from second)?
Related
The Room persistence library defines databases to provide its Daos.
#Database(...)
abstract class DbImpl : RoomDatabase() {
abstract val daoImpl: DaoImpl
}
How could I provide all DAOs in Dagger, without the need to provide these manually with a Module?
#Provides
fun provideDaoImpl(
db: DbImpl,
) = db.daoImpl
You can declare the Room database as a component dependency, thus implicitly provide any declared DAOs from it.
The benefit of this approach is that you save some boilerplate as you don't need the #Provides methods wrapping every DAO. The downside is that the Room database now needs to be created along with your component to link it as a dependency which may incur unnecessary work at app-startup.
I'd stick with the #Provides methods and the boilerplate module. Your DAOs hopefully don't change that much that this would be hard to maintain and it gives you the benefit of being able to create the database lazily when needed. Just make sure that you avoid scoping your DAO wrapper methods, as Room already does some internal double-locking.
With the Android Architecture components and the MVVM pattern I have some question.
Based on most examples around the web there are usually simple examples.
Have an entity for Room
#Entity
public class User{
...
}
Have a DAO
#Dao
public interface UserDao{
...
}
Have a repository
public class UserRepository{
}
ViewModel
public class UsersListViewModel extends AndroidViewModel{
....
}
Now let's extend this and beside user have user_access and user_actions for instance, so have 3 tables.
Questions:
For each table in Room I create entities. Should I have 3 Dao one for each entity (userDao, userAccessDao, userActionsDao) or just a general AppDao class?
Same goes for Repository. One repository for the entire app or Repositories for each Entitiy (RepositoryUser, RepositoryUserAccess, RepositoryUserActions?
If my app has one main activity and multiple fragments, should I create one ViewModel for each fragment?
1
You should have contextual DAOs, let's say an UserDao which should contains the queries related to the users, if you have posts in your app, you should have a PostDao for everything related to posts.
2
Same logic for repositories, remember the Single Responsibility Principle for classes, sticking to that principle you should have repositories for each kind of entities separated (UserRepository, PostRepository...).
3
Following all the new concepts described as Jetpack you should have one viewmodel per fragment, unless for one strange reason you have two fragments that need the exact same logic, and that is very unlikely to happen since the objective of a fragment is to be reused.
just got started with android room database an I like the efficiency it brings to the android team and the general programming experince. But currently facing some efficiency issues .
my issue is that for a class marked with #database annotation we are recqured to pass all the enties inside the annotation as google explains https://developer.android.com/training/data-storage/room/
#Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
so what if I have like over 50 entity classes and I want to easen the process of passing the classes my Database class is there any option for me ?? I happen to come from a spring background and I like the similarity between the two though in spring there is no such a condition but everything works smoothly
so what if I have like over 50 entity classes and I want to easen the process of passing the classes my Database class is there any option for me ?
Room cannot make assumptions about which RoomDatabase the visible #Entity classes belong to. For example, WorkManager might use Room, and if it does, the WorkManager entities belong to its database, not yours.
You could write some sort of code generator that uses your own personal rules to generate that list of classes, if you wanted.
I started working in a project that already had Realm and the MVVM structure on it. As of now, all Realm methods are static and inside a RealmHelper class, except for some methods that are in the ViewModel classes of it's respective Activity. But RealmHelper class is starting to get bigger and bigger and kinda messy. I wanted to know what are your suggestions to rearrange my methods and classes when using Realm.
It's perfectly fine if you want to keep the RealmHelper class which manages all of the methods that your app can access. You may want to try to convert the methods to one liners that are being directed to another class internally.
So the structure might look something like this:
co.your.app.realmhelper
RealmHelper [public]
WriterHelper [Package Private]
ReaderHelper [Package Private]
So all of your logic is actually happening within the package private classes but the rest of your app would interface with the RealmHelper. The RealmHelper would just manage the instances of the package private classes and determine which methods should be invoked for those classes.
Your other option is to get rid of the RealmHelper in favor of smaller classes. Without knowing what your RealmHelper is actually doing it's difficult to give additional advice.
I have written a custom TestRule to use with my Android test suite. It populates a table in the database used by the app under test. Now I need to use this DataRule along with ActivityTestRule. Can I have two fields of my test class annotated with #Rule? How do I control the order in which the rules are applied?
Background:
The Android API provides a TestRule for starting an Activity which is the core class for every app with a UI. My app has a database and I have several tests which require the database to be pre-populated with some known data. Previously, with JUnit3-based tests, I used an abstract superclass to centralize the code which prepares the database and then I extended this superclass for different test cases. Now I am trying to implement the same logic using JUnit 4. I learned recently that test rules are one way to provide logic which is reused across tests, so I am trying to move the logic from my superclass to a test rule. Is this an appropriate way to achieve my goal?
You certainly can have multiple #Rule fields in a single test. I'm not sure what the default ordering of rule application is, or if it's even well-defined. However, if ordering is important you can control it with a RuleChain
which allows you to define an order on how rules are applied when you have multiple rules in a test case.
From the Javadoc...
#Rule
public RuleChain chain = RuleChain
.outerRule(new LoggingRule("outer rule")
.around(new LoggingRule("middle rule")
.around(new LoggingRule("inner rule");
RuleChain is deprecated and since 4.13 you can make use of order parameter in Rule.
org.junit.Rule annotation has a parameter "order" which you can use to order the Rules in one file.
check the doc in the link below
Rule.java
If you're using JUnit for your tests, which I personally recommend, it's not recommended to have multiple rules in the same file, because a Rule is a unit of your test, and as you're doing unit tests, you should have just one Rule per file.
If you need to create some sort of data before you run your tests you should use the #Before and then load the necessary information.
More on this can be found here: http://junit.sourceforge.net/javadoc/org/junit/Before.html
If you have to load the same data in multiple classes, I would recommend you to create a class with your logic, extend that class in your test class and then create a method annotated with #Before an call your super class method.
Hope that helps