Dears. I used to develop Android apps using MVP pattern and now I'm trying the MVVM with Architecture components like DataBind and LiveData.
I wrote my Repository class that provides a LiveData:
LiveData<MyEntity> getById(long id);
For Activity/Fragments I observe the LiveData exposed by ViewModel (that uses my Repository) and everything works fine.
The problem is I have to schedule an Alarm to display a Notification with a text related to MyEntity, so I created an Intent containing my MyEntityId as an Extra.
When the AlarmManager calls my BroadcastReceiver, I need to use the Repository to get MyEntity. The point is how to "Observe" the LiveData inside a non-UI component.
Also, I can start an IntentService (background thread) to avoid accessing the Repository in the Main Thread, and use something like "blockingNext" from RxJava, but I still could not figure a way to wait for LiveData.
What is the correct way of doing this? Note that my Repository may not be implemented using Room, due to legacy issues.
Thanks
The only solution I figured so far was have methods like this in the Repository:
LiveData<MyEntity> getByIdLive(long id);
MyEntity getById(long id);
But this does not look good for me. So I'd like to ask how is the correct way of implement this.
Best Regards
It's better to avoid such things, but if you really need it and really know what you're doing you can try the following code:
public static <T> void observeOnce(final LiveData<T> liveData, final Observer<T> observer) {
liveData.observeForever(new Observer<T>() {
@Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
@WorkerThread
public static <T> T waitSync(final LiveData<T> liveData) {
final Object lock = new Object();
final Object[] result = new Object[1];
final boolean[] resultReady = new boolean[] {false};
(new Handler(Looper.getMainLooper())).post(new Runnable() {
@Override
public void run() {
observeOnce(liveData, new Observer<T>() {
@Override
public void onChanged(T t) {
synchronized (lock) {
result[0] = t;
resultReady[0] = true;
lock.notify();
}
}
});
}
});
synchronized (lock) {
try {
while (!resultReady[0]) {
lock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
return (T) result[0];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With