I'm currently working on an App and wanted to use the current state of the art libaries for Android: RxAndroid, Dagger2 and Realm. I couldn't find good examples in the net, so I have to ask here.
public Observable<Bla> getBla() {
Bla b = realm.where(Bla.class).findFirst();
return Observable.just(b);
}
In most cases Realm queries run on UIThread, so why I shound't just return the result as List instead of
Observable<List<Bla>>
Maybe someone knows a very good example with realm in this lib conbination?
@Inject
TableService mTableService;
(Code below)
@Singleton
@Component(modules = {AppModule.class, ServiceModule.class})
public interface AppComponent {
void inject(MainActivity activity);
}
@Singleton
@Component(modules = {AppModule.class, ServiceModule.class})
public interface ServiceComponent {
void inject(MainActivity activity);
}
public class AppModule {
Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Provides
@Singleton
Application providesApplication() {
return mApplication;
}
@Provides
@Singleton
RealmConfiguration provideRealmConfiguration(Application application) {
return new RealmConfiguration.Builder(application)
.schemaVersion(1)
.deleteRealmIfMigrationNeeded()
.build();
}
@Provides
Realm provideRealm(RealmConfiguration realmConfiguration) {
try {
return Realm.getInstance(realmConfiguration);
} catch (Exception cause) {
Realm.deleteRealm(realmConfiguration);
return Realm.getInstance(realmConfiguration);
}
}
}
@Module
public class ServiceModule {
public ServiceModule() {
}
@Provides
@Singleton
GuestService provideGuestService(Realm realm) {
return new GuestService(realm);
}
}
public class Application extends android.app.Application {
private AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
mAppComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
public AppComponent getAppComponent() {
return mAppComponent;
}
}
Thank you!
1.) RealmResults<T>
is auto-updating, and if you add a RealmChangeListener
to your RealmResults
, then it will be called whenever the underlying data has changed.
private final RealmChangeListener listener = new RealmChangeListener() {
@Override
public void onChange(Object results) {
notifyDataSetChanged();
}
};
But when you call asObservable()
on a RealmResults
, then an Observable<RealmResults<T>>
is created that automatically appends a RealmChangeListener
that notifies you of changes, and removes it when you unsubscribe. You can look at the exact behavior if you check the default RealmObservableFactory implementation.
So it really is a shorthand for adding a RealmChangeListener
to your results so that you can update your views whenever.
Subscription subscription = RxTextView.textChanges(editText).switchMap(charSequence ->
realm.where(SomeObject.class)
.contains("searchField", charSequence.toString(), Case.INSENSITIVE)
.findAllAsync()
.asObservable())
.filter(RealmResults::isLoaded) //
.subscribe(objects -> adapter.updateData(objects));
2.) You probably have specified an @Inject
annotated constructor.
public class TableService {
@Inject
Application application;
@Inject
public TableService() {
}
}
3.) Typically you should have 1 component / scope.
EDIT:
- Why should I use Observable as return type for Realm queries?
public Observable<Bla> getBla() {
Bla b = realm.where(Bla.class).findFirst();
return Observable.just(b);
}
This doesn't really make sense to use with Realm, because it doesn't listen to changes.
It's more reasonable to use
public Observable<Blah> getBla() {
Blah blah = realm.where(Blah.class).findFirst();
if(blah == null) {
return Observable.empty();
} else {
return blah.asObservable();
}
}
Although personally I advise to use Observable<RealmResults<T>>
because it is more reliable.
3.) Not sure what you mean. Service Component is not working without @component appModule.class, but it should be in my understanding.
There shouldn't even be a ServiceComponent
. Just @Component SingletonComponent
.