I'm introducing myself to rxJava2 in Android with MVP.
For initial steps I have created an Activity, a presenter and a Model objects (every of them with an interface class).
In my activity, I create the presenter, and try to load data, notifying the view when it is ready:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
MvpPresenter presenter = new Presenter(this,
AndroidSchedulers.mainThread());
presenter.loadData();
Inside the presenter, on loadData method, just calling back to view
@Override
public void loadData() {
compositeDisposable.add(dataRepository.getDataList().
subscribeOn(Schedulers.io()).
observeOn(mainScheduler).
subscribeWith(new DisposableSingleObserver<List<Book>>() {
@Override
public void onSuccess(@NonNull List<Book> bookList) {
if (!bookList.isEmpty())
view.displayBooks(bookList);
else
view.displayEmpty();
}
@Override
public void onError(@NonNull Throwable e) {
view.displayError("boooom");
}
}));
}
Method getBooks() is as follows (I have in mind to use an API, but so far, for simplicity purposes, I just have the data hardcoded)
public Single<List<Shelf>> getShelfList() {
return Single.fromCallable(new Callable<List<Book>>() {
@Override
public List<Book> call() throws Exception {
Book b1 = new Book();
Book b2 = new Book();
Book b3 = new Book();
List<Book> bookList = Arrays.asList(b1,b2,b3);
return bookList;
}
});
}
The method view.displayBooks(bookList) just have a Toast message (again, for simplicity purposes)
public void displayBooksInShelf(List<Shelf> shelfList) {
Toast.makeText(this, shelfList.size(), Toast.LENGTH_LONG).show();
}
Seems very simple and it should the Toast as three books are returned correctly... but when executing, it throws an exception:
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.
at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2
at android.content.res.Resources.getText(Resources.java:331)
at android.widget.Toast.makeText(Toast.java:287)
In Unitary Test (Mockito) everything seems to work fine, but together it fails. My suspects are that there is some kind of thread issue. Anybody can help my with this problem?
Also, knowing that I'd like to use retrofit, is the approach I'm using the correct one? Or maybe the thread should be managed in the Model/Repository class?
Hope the information I've provided is enough to clarify where the problem is
Thanks in advance!
Notice this line in the stacktrace:
You are trying to access
String
resource with invalid resource id. Here where it happens:The second argument must be
String
message orint
resource id. You are passingint
here, so compiler chooses overload with a resource id (obviously invalid).If you want to just print
int
you have to passString
representation of it: