I'm trying to run an async call (enqueue method) and in the "onResponse" method I save to Realm (the realm.io library) some data, and refresh a recyclerview. Last call is that I stop a "SwipeRefreshLayout" to show the loading circle.
I'm having weird behaviour since if I run realm directly in the onResponse method, I get an issue from realm telling me that I'm not on the UI Thread (but the documentation of callback says I should be!).
So it works if I put the realm code in runOnUIThread method.
The problem arises if then I put the swiperefreshLayout out of this force to UI method. I get an exception form the framework telling me that I'm touching the view outside of the thread that generated it, but shouldn't be!
In addition, if i compare loopers it says false!
public void onResponse(Response<Publication> response, Retrofit retrofit) {
try {
//get the response object
dailies = response.body().getIssues();
Log.i(TAG, "Check loopers=" + (Looper.getMainLooper() == Looper.myLooper()));//Always false!
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
List<RealmIssue> realmIssues = new ArrayList<>();
RealmIssue realmIssue;
for (Issue issue : dailies) {
realmIssue = new RealmIssue(issue);
mRealmInstance.beginTransaction();
realmIssue = mRealmInstance.copyToRealmOrUpdate(realmIssue);
mRealmInstance.commitTransaction();
realmIssues.add(realmIssue);
Log.w("TEST", "Items copied to realm: " + realmIssues.size());
mRefreshLayout.setRefreshing(false);//Here works
//mRefreshLayout.setRefreshing(false);//Here does NOT work
I'm not sure if it's an issue of the library or mine mistake, in case of the latter, please forgive me!
EDIT: I forgot to say, if it is important (and I think it is) that I'm running a mock retrofit for now:
MockRetrofit mockRetrofit = new MockRetrofit(NetworkBehavior.create(), new CallBehaviorAdapter(retrofit, Executors.newSingleThreadExecutor()));
Thank you both for the answers,let me start from @eneim
I've seen their example but for now I'm still dealing with normal DTOs, my adapter was not using the real items, in fact I've reworked the code and completely removed Realm usage in the class and the issue is still there, so now I'm focused on Retrofit.
@JakeWharton thank you jake, I've created a Gist with the relevant code here:
https://gist.github.com/ndorigatti/1ae58b33bfd52a24746e
I've put the logcat I'm obtaining using that code, with how I create the mock executor (Taken directly from the Examples). I have to be honest that I just copied that part and did not dig on if it is the correct way or not.
The code in the gist should be enough since I'm doing nothing special, just initialize the recyclerview and the swiperefreshlayout in onCreate and call the doRetrofitRequest method. As you can see, no more realm code.
Here you are my dependencies, just to give you all the possible information (not all of them are used in that activity):
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.android.support:cardview-v7:22.2.0'
compile 'com.android.support:recyclerview-v7:22.2.0'
compile 'com.android.support:design:22.2.0'
compile files('libs/itextg-5.4.4.jar')
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.5.0'
//compile 'com.squareup.okhttp:okhttp:1.2.1'
compile('de.keyboardsurfer.android.widget:crouton:1.8.5') {
exclude module: 'support-v4'
compile 'com.android.support:support-v4:21.0.3'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:retrofit-mock:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta2'
compile ('org.simpleframework:simple-xml:2.7.1'){
exclude group: 'stax', module: 'stax-api'
exclude group: 'stax', module: 'stax'
exclude group: 'xpp3', module: 'xpp3'
compile 'io.realm:realm-android:0.84.2'
Sorry for being so long, I just want to understand the problem. If you need a test project, I will try to set it up without the code I can't share ;)
Thank you
EDIT: With non-mocked version of the retrofit it is working as expected.
I took some time to dig in the code, just found that:
Log.i(TAG,"Retrofit callbackExcecutor: " + retrofit.callbackExecutor());
gives null and hence the mocked version in BehaviorCall (constructor):
if (callbackExecutor == null) {
callbackExecutor = new Executor() {
@Override public void execute(Runnable command) {
command.run();
Maybe it is this the issue?
I've found that the non-mocked retrofit does in Retrofit class:
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(Platform.get().defaultCallAdapterFactory(callbackExecutor));
And then in Platform class:
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
if (callbackExecutor == null) {
callbackExecutor = new MainThreadExecutor();
return new ExecutorCallAdapterFactory(callbackExecutor);
So it seem that the non-mocked version correctly handles platform and non-provided executors in android, while the mocked one just creates a default executor on a thread pool (right?).
Do you think this is a bug or works as expected on your side?
I fixed it by forcing a "MainThreadExecutor" to my retrofit builder for now (until I'm on testing and mocking phase).
Sorry for the multiple replies.
Retrofit 2.0.0 beta2 Asychronous Callbacks and threads
Mock Call not using callback executor
Nov 25, 2015
Hello, not sure if it's related, but I have a problem with my ErrorHandlingCallAdapter not executing callback on MainThread.
Here's my stackoverflow post about it: http://stackoverflow.com/questions/33974146/retrofit-2-0-custom-calladapterfactory-callbacks-not-happening-on-mainthread
Thanks!