Why doesn't my Android ViewModel's Room RxJava3 Flowable publish any result when my Activity is paused? - android-room

I'm aware it's a complex question that cannot have a definite answer without posting a few hundreds of lines of code, which is why I'm looking for help through general ideas and pointers.
I have a Room #Query returning a RxJava3 Flowable<List<...>> which I subscribe to on RxJava thread Schedulers.io(), and observe from an activity-scoped ViewModel on RxJava thread AndroidSchedulers.mainThread(). The data is then stored in my ViewModel as LiveData, which plays better than RxJava when it comes to handle Android components' lifecycle.
The idea is to have a clean and immediate data update pattern, not to have to handle disposal and re-subscription separately on each activity or fragment lifecycle event such as onPaused and onResumed, and being updated in the background even when my activity is hidden in order to avoid that awful refresh lag when returning to my activity. I was pretty amazed at that design pattern. I still am, but I'm beginning to have doubts.
When starting another activity with the same design pattern, I do change a value and immediately get an updated List<...> from the other ViewModel. Different Activity, different ViewModel, same design, same database table. When returning to the first Activity, I find that the new data does never get updated: Room did not emit any update even though the data set has changed. I have to dispose and subscribe again in order to see the new data.
So my question is: any pointer on where the source of my problem might be?! Is there something rotten in the core of this design pattern? Something I misunderstood about all those things are supposed to work together? Is it just a mistake of mine due to some threading issue? Or should I fill a bug report for Room?
I tried to observe another non-Room RxJava3 observable from the ViewModel of my first Activity, and it does get updates when its data set is updated.
By the way, I also use Hilt in order to inject eveything as #Singleton.
Thank you for your time :-)

After a week of headaches, I have finally stumbled upon a solution, which happens to be clean and elegant.
The issue was RxJava, which, I just learnt, is not supposed to seamlessly handle multiple subscriptions to the same Observable. The solution is supposedly to make use of the publish(), connect(), refcount() operators, or better use the shortcut share(). I tried every way I could think of, without success (it actually made it worse). I also tried to subscribe() to the Room Flowable from my repository and proxy it through a BehaviorSubject.
There was this weird org.reactivestreams.Publisher in Room's documentation, whose added value I wouldn't know, and whose origin wasn't even my familiar io.reactivex.rxjava3. It turns out it that was the solution. Edit: It turns out Publisher is an interface that Flowable happens to implement.
build.gradle
implementation 'android.arch.lifecycle:reactivestreams:+'
Dao.java
#Query("...")
Flowable<List<...>> getFlowable();
ViewModel.java
public liveData;
#Inject
public ViewModel(#NonNull RoomDatabase roomDatabase) {
liveData = LiveDataReactiveStreams.fromPublisher(roomDatabase.dao().getFlowable());
}
It seems too easy to be true, but as far as I can see it seems to work perfectly better this way.
Edit:
It turns out the root of this issue was a slight little bit more vicious than I thought. I assumed #InstallIn(SingletonComponent.class) in my dependency injection #Module was enough, but apparently a #Singleton annotation on each #Provides method is also required.
#Module
#InstallIn(SingletonComponent.class)
public abstract class DependencyInjection
{
#Provides
#NonNull
#Singleton // do not omit this
public static DataDao provideDataDao(#NonNull RoomDatabase roomDatabase) {
return roomDatabase.dataDao();
}
#Provides
#NonNull
#Singleton // do not omit this
public static RoomDatabase provideRoomDatabase(#ApplicationContext Context applicationContext) {
return
BuildConfig.DEBUG ?
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").fallbackToDestructiveMigration().build() :
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").build() ;
}
}

Related

Xamarin Async Constructor

For my application I need to fetch some data asynchronously and do some initialization for each page. Unfortunately, a constructor does not allow me to make asynchronous calls. I followed this article and put all of my code into the OnAppearing method. However, since then I ran into multiple issues since each platform handles the event a little bit differently. For example, I have pages where you can take pictures, on iOS the OnAppearing is called again every time after the camera is closed while Android doesn't. It doesn't seem like a reliable method for my needs, which is also described here:
Calls to the OnDisappearing and OnAppearing overrides cannot be treated as guaranteed indications of page navigation. For example, on iOS, the OnDisappearing override is called on the active page when the application terminates.
I am searching for a method/way where I can perform my own initialization. The constructor would be perfect for that but I cannot perform anything asynchronously in there. Please do not provide me with any work arounds, I am searching for a solution that is the "recommended" way or maybe someone with a lot of experience can tell me what they are doing. (I also don't want to .Wait() or .Result as it will lock my app)
You can use Stephen Cleary's excellent NotifyTaskCompletion class.
You can read more how it works and what to do/don't in these cases in Microsoft's excellent Async Programming : Patterns for Asynchronous MVVM Applications: Data Binding. The highlights of this topics are:
Let’s walk through the core method
NotifyTaskCompletion.WatchTaskAsync. This method takes a task
representing the asynchronous operation, and (asynchronously) waits
for it to complete. Note that the await does not use
ConfigureAwait(false); I want to return to the UI context before
raising the PropertyChanged notifications. This method violates a
common coding guideline here: It has an empty general catch clause. In
this case, though, that’s exactly what I want. I don’t want to
propagate exceptions directly back to the main UI loop; I want to
capture any exceptions and set properties so that the error handling
is done via data binding. When the task completes, the type raises
PropertyChanged notifications for all the appropriate properties.
A sample usage of it:
public class MainViewModel
{
public MainViewModel()
{
UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
}
public NotifyTaskCompletion<int> UrlByteCount { get; private set; }
}
Here, the demo is about binding the returned asynchronous value to some bindable property, but of course you can you is without any return value (for simple data loading).
This may be too simple to say, but you CAN run asynchronous tasks in the constructor. Just wrap it in an anonymous Task.
public MyConstructor() {
Task.Run(async () => {
<Your code>
}
}
Be careful when doing this though as you can get into resource conflict issues if you accidentally open the page twice.
Another thing I like to do is use an _isInit flag, which indicates a first time use, and then never again.

Single responsibility principle - function

I'm reading some tuts about SOLID programming, and I'm trying to refactor my test project to implement some of those rules.
Often I have doubts with SingleResponsibilityPrinciple, so I hope someone could help me with that.
As I understood, SRP means that (in case of a function), function should be responsible for only one thing. And that's seems pretty easy and simple, but I do get in a trap of doing more than thing.
This is simplified example:
class TicketService {
private ticket;
getTicket() {
httpClient.get().then(function(response) {
ticket = response.ticket;
emit(ticket); <----------------------
});
}
}
The confusing part is emit(ticket). So, my function is named getTicket, that's exactly what I'm doing there (fetching it from server e.g.), but on the other hand, I need to emit that change to all other parts of my application, and let them know that ticket is changed.
I could create separate set() function, where I could do setting of private variable, and emit it there, but that seems like a same thing.
Is this wrong? Does it break the rule? How would you fix it?
You could also return the ticket from the getTicket() function, and then have a separate function called setUpdatedTicket() that takes a ticket and sets the private parameter, and at the end calls the emit function.
This can lead to unexpected behavior. If I want to re-use your class in the future and I see with auto-completion in my IDE the method getTicket() I expect to get a Ticket.
However renaming this method to mailChangedTicket, ideally you want this method to call the getTicket method (which actually returns the ticket) and this way you have re-usable code which will make more sense.
You can take SRP really far, for example your TicketService has a httpClient, but it probably doesn't matter where the ticket comes from. In order to 'fix' this, you will have to create a seperate interface and class for this.
A few advantages:
Code is becoming more re-usable
It is easier to test parts separately
I can recommend the book 'Clean Code' from Robert C. Martin which gives some good guidelines to achieve this.

Seemingly redundant event and event handlers

I will explain with an example. My GWT project has a Company module, which lets a user add, edit, delete, select and list companies.
Of these, the add, edit and delete operations lands back the user on the CompanyList page.
Thus, having three different events - CompanyAddedEvent, CompanyUpdatedEvent and CompanyDeletedEvent, and their respective event handlers - seems overkill to me, as there is absolutely not difference in their function.
Is it OK to let a single event manage the three operations?
One alternative I think is to use some event like CompanyListInvokedEvent. However, somewhere I think its not appropriate, is the event actually is not the list being invoked, but a company being added/updated/deleted.
If it had been only a single module, I would have get the task done with three separate events. But other 10 such modules are facing this dilemma. It means 10x3 = 30 event classes along with their 30 respective handlers. The number is large enough for me to reconsider.
What would be a good solution to this?
UPDATE -
#ColinAlworth's answer made me realize that I could easily use Generics instead of my stupid solution. The following code represents an event EntityUpdatedEvent, which would be raised whenever an entity is updated.
Event handler class -
public class EntityUpdatedEvent<T> extends GwtEvent<EntityUpdatedEventHandler<T>>{
private Type<EntityUpdatedEventHandler<T>> type;
private final String statusMessage;
public EntityUpdatedEvent(Type<EntityUpdatedEventHandler<T>> type, String statusMessage) {
this.statusMessage = statusMessage;
this.type = type;
}
public String getStatusMessage() {
return this.statusMessage;
}
#Override
public com.google.gwt.event.shared.GwtEvent.Type<EntityUpdatedEventHandler<T>> getAssociatedType() {
return this.type;
}
#Override
protected void dispatch(EntityUpdatedEventHandler<T> handler) {
handler.onEventRaised(this);
}
}
Event handler interface -
public interface EntityUpdatedEventHandler<T> extends EventHandler {
void onEventRaised(EntityUpdatedEvent<T> event);
}
Adding the handler to event bus -
eventBus.addHandler(CompanyEventHandlerTypes.CompanyUpdated, new EntityUpdatedEventHandler<Company>() {
#Override
public void onEventRaised(EntityUpdatedEvent<Company> event) {
History.newItem(CompanyToken.CompanyList.name());
Presenter presenter = new CompanyListPresenter(serviceBundle, eventBus, new CompanyListView(), event.getStatusMessage());
presenter.go(container);
}
});
Likewise, I have two other Added and Deleted generic events, thus eliminating entire redundancy from my event-related codebase.
Are there any suggestions on this solution?
P.S. > This discussion provides more insight on this problem.
To answer this question, let me first pose another way of thinking about this same kind of problem - instead of events, we'll just use methods.
In my tiered application, two modules communicate via an interface (notice that these methods are all void, so they are rather like events - the caller doesn't expect an answer back):
package com.acme.project;
public interface CompanyServiceInteface {
public void addCompany(CompanyDto company) throws AcmeBusinessLogicException;
public void updateCompany(CompanyDto company) throws AcmeBusinessLogicException;
public void deleteCompany(CompanyDto company) throws AcmeBusinessLogicException;
}
This seems like overkill to me - why not just reduce the size of this API to one method, and add an enum argument to simplify this. This way, when I build an alternative implementation or need to mock this in my unit tests, I just have one method to build instead of three. This gets to be clearly overkill when I make the rest of my application - why not just ObjectServiceInterface.modify(Object someDto, OperationEnum invocation); to work for all 10 modules?
One answer is that you might want want to drastically modify the implementation of one but not the others - now that you've reduced this to just one method, all of this belongs inside that switch case. Another is that once simplified in this way, the inclination often to further simplify - perhaps to combine create and update into just one method. Once this is done, all callsites must make sure to fulfill all possible details of that method's contract instead of just the one specific one.
If the receivers of those events are simple and will remain so, there may be no good reason to not just have a single ModelModifiedEvent that clearly is generic enough for all possible use cases - perhaps just wrapping the ID to request that all client modules refresh their view of that object. If a future use case arises where only one kind of event is important, now the event must change, as must all sites that cause the event to be created so that they properly populate this new field.
Java shops typically don't use Java because it is the prettiest language, or because it is the easiest language to write or find developers for, but because it is relatively easy to maintain and refactor. When designing an API, it is important to consider future needs, but also to think about what it will take to modify the current API - your IDE almost certainly has a shortcut key to find all invocations of a particular method or constructor, allowing you to easily find all places where that is used and update them. So consider what other use cases you expect, and how easily the rest of the codebase can be udpated.
Finally, don't forget about generics - for my example above, I would probably make a DtoServiceInterface to simplify matters, so that I just declare the one interface with three methods, and implement it and refer to it as needed. In the same way, you can make one set of three GwtEvent types (with *Handler interfaces and possibly Has*Handlers as well), but keep them generic for all possible types. Consider com.google.gwt.event.logical.shared.SelectionEvent<T> as an example here - in your case you would probably want to make the model object type a parameter so that handlers can check which type of event they are dealing with (remember that generics are erased in Java), or source from one EventBus for each model type.

Static? Repositories MVC3, EF4.2 (Code First)

I'm new to MVC, EF and the like so I followed the MVC3 tutorial at http://www.asp.net/mvc and set up an application (not yet finished with everything though).
Here's the "architecture" of my application so far
GenericRepository
PropertyRepository inherits GenericRepository for "Property" Entity
HomeController which has the PropertyRepository as Member.
Example:
public class HomeController
{
private readonly PropertyRepository _propertyRepository
= new PropertyRepository(new ConfigurationDbContext());
}
Now let's consider the following:
I have a Method in my GenericRepository that takes quite some time, invoking 6 queries which need to be in one transaction in order to maintain integrity. My google results yeldet that SaveChanges() is considered as one transaction - so if I make multiple changes to my context and then call SaveChanges() I can be "sure" that these changes are "atomic" on the SQL Server. Right? Wrong?
Furthermore, there's is an action method that calls _propertyRepository.InvokeLongAndComplex() Method.
I just found out: MVC creates a new controller for each request. So I end up with multiple PropertyRepositories which mess up my Database Integrity. (I have to maintain a linked list of my properties in the database, and if a user moves a property it needs 6 steps to change the list accordingly but that way I avoid looping through all entities when having thousands...)
I thougth about making my GenericRepository and my PropertyRepository static, so every HomeController is using the same Repository and synchronize the InvokeLongAndComplex Method to make sure there's only one Thread making changes to the DB at a time.
I have the suspicion that this idea is not a good solution but I fail to find a suitable solution for this problem - some guys say that's okay to have static repositories (what happens with the context though?). Some other guys say use IOC/DI (?), which sounds like a lot of work to set up (not even sure if that solves my problem...) but it seems that I could "tell" the container to always "inject" the same context object, the same Repository and then it would be enough to synchronize the InvokeLongAndComplex() method to not let multiple threads mess up the integrity.
Why aren't data repositories static?
Answer 2:
2) You often want to have 1 repository instance per-request to make it easier to ensure that uncommited changes from one user don't mess things up for another user.
why have a repository instance per-request doesn't it mess up my linked list again?
Can anyone give me an advice or share a best practice which I can follow?
No! You must have a new context for each request so even if you make your repositories static you will have to pass current context instance to each its method instead of maintaining single context inside repository.
What you mean by integrity in the first place? Are you dealing with transactions, concurrency issues or referential constraints? Handling all of these issues is your responsibility. EF will provide some basic infrastructure for that but the final solution is still up to your implementation.

wicket: how to update a component after AjaxLazyLoadPanel?

I have a page that has a status text label and a panel doing some DB query. since the query can take some time I am loading it using
add(new AjaxLazyLoadPanel("resultPanel")
{
#Override
public Component getLazyLoadComponent(String id) {
return new SearchResultPanel(id);
}
};
which works very well.
My question is how to update the status label which is outside of the resultPanel, to show the number of search results?
I was thinking along the lines of addComonent(target) but I don't have a target? am i off the track?
Well the SearchResultPanel might look like this:
public class SearchResultPanel extends Panel implements IHeaderContributor{
public SearchResultPanel(String id){
super(id);
....
}
public void renderHead(IHeaderResponse response){
response.renderOnDomReadyJavascript("alert('hello');");
}
}
Now when it is loaded it should throw out that javascript. Another way answered on stackoverflow previously (though I do not like it) is to use an AjaxSelfUpdatingTimerBehavior, which unless the javascript should be ran more then once I do not like, and still it is less elegant in my opinion.
Look here for their answer: Wicket: reload AjaxLazyLoadPanel automatically
You can always obtain the current request target using RequestCycle.get().getRequestTarget(), provided that there is an active request cycle, so in theory you could do that from your lazy-loaded component constructor, check if it is an Ajax target, and add the component if it is.
Another solution is to look at the source code of AjaxLazyLoadPanel and create your own component based on it. (It's really simple but as you can see if you look at the code, there's no way you can make it expose the request target. This isn't a very OO thing to do, but as all the important functionality is wrapped in the constructor, you have very little choice..
I would avoid having to tamper with Javascript, unless there's really no other way.
Happened to come across this post and I have something to add as well.
The AjaxLazyLoadPanel now has an overridable method called onComponentLoaded(Component, AjaxRequestTarget) which could also solve your problem.

Resources