Realm-java: Cannot resolve method refresh()

Created on 24 May 2016  路  29Comments  路  Source: realm/realm-java

I've been using Realm 0.91.0 version on Android. but some core method isn't found... like refresh(), clear(), allObjects(). I welcome If you have suggestions or solutions about how to use those above methods.

Thanks in Advance :-)

Code Sample

> public Realm realm;

   public void refresh(){
        realm.refresh();
   }

   public void clearAll(){
        realm.beginTransaction();
        realm.clear();
        realm.commitTransaction();
    }

    public Boolean hasCustomers(){
        return !realm.allObjects(NewCustomer.class).isEmpty();
    }

Version of Realm and tooling

Realm version(s): 0.91.0

Android Studio version: 2.1.1

Which Android version and device: Android N preview and Nexus 4

T-Help

Most helpful comment

That is correct.
If you need to refresh in the middle of the Looper thread, you are most likely doing something wrong.

All 29 comments

Hi @abdulgaffar291
refresh was deprecated in 0.90 and removed in 0.91. You should either use realm.waitForChange() or open a new Realm instance as appropriate.

Hi Melchior

Thanks for your info, and what about clear() and allObjects() methods.

clear was deprecated in 0.88. You should use deleteAllFromRealm() instead. allObjects was deprecated and you should use where().findAll() instead.

The last two releases have been streamlining a lot of API's, but we don't plan to break stuff quite as much going forward. Sorry for the confusion.

ok Melchior. Very Thanks.

But waitForChange() cannot be used on looper threads, right?

That is correct.
If you need to refresh in the middle of the Looper thread, you are most likely doing something wrong.

Ah, I see, waitForChange() is a way to force a non-looper thread to update to the latest revision.

If you need to refresh in the middle of the Looper thread, you are most likely doing something wrong

That's a bit of a rough statement though considering realm.commitTransaction() used to do that on the looper thread before 0.89.0 :tongue:

But then again, you shouldn't be writing on the main thread in the first place. That's where the ANRs dwell.

commitTransaction is a bit different. Your right it still refreshes the UI thread, but the reason for using refresh is only if you are expecting a change from another thread to have occurred. For this purpose the change listeners are much better. waitForChange was introduced to solve the other major use-case which is having some sort of loop on a background thread.

In general though, either use change listeners on the UI thread or open/close Realms on worker threads would be the best practise.

Is showStatus() method also deprecated.

We don't have a showStatus method?

@abdulgaffar291 there is no showStatus() method in Java, that's your own code

@cmelchior change listeners are neat, but the fine-grained notifications will be what'll make it truly powerful.

for debugging i've installed stetho. on stetho inititalization i got this bug.

cannot resolve symbol MyDumperPlugin()

@abdulgaffar291 you mean stetho-realm? You should update that to the newest version, there have been some changes here and there.

yeah absolutely. i installed version 1.3.1

And Stetho-Realm version...?

If you are not using Stetho-Realm, and this is a Stetho bug; then it's not a Realm bug, despite this being a Realm issue.

compile 'com.facebook.stetho:stetho:1.3.1' this is the stetho version i've used.

how do i resolve this error: cannot find symbol class MyDumperPlugin

@abdulgaffar291 That seems to be a problem with Stetho, not Realm. Unfortunately I don't have any suggestion what could be wrong. Perhaps @zaki50 has an idea.

What was the reason to remove refresh()?
I'm often using it in testcases:

  • Click something (the UI thread does something on the realm)
  • realm.refresh() on my instrumentation test class
  • be happy

To be fair, in this case waitForChange() directly after the click() order would work. I sometimes have to wait for onCreate() of the fragment to finish. refresh() seems much more natural. Using waitForChange() to refresh the realm seems like a hack and won't work if you aren't sure if a change happened (e.g. the user clicked something or not).

refresh() forced the synchronization to the new version for all (synchronous?) realm results, but the auto-sync in transactions and on commitTransaction() was removed specifically so that iterators would not break with ConcurrentModificationException.

This way, the API shows clearly that if you want to be notified of a change, you should do that using a change listener, which happens when the Realm updates through the REALM_CHANGED event.

However, I believe the following would work for your use-case.

package io.realm;

public class RealmRefresh {
    public static void refreshRealm(Realm realm) {
        realm.checkIfValid();
        if(realm.isInTransaction()) {
            throw new IllegalStateException("Cannot refresh inside of a transaction.");
        }
        realm.sharedGroupManager.advanceRead();
        realm.handlerController.refreshSynchronousTableViews();
    }
}

But if you need to refresh only one RealmResults, you can call the package-protected method syncIfNeeded(), that's what refreshSynchronousTableViews() does, after all.

Oh that's a nice idea. Good enough for my test suite. Thanks!

It looks like this issue has been addressed and answered so I will now close it. Please contact us for any other enquiry! :)

Just for future reference, in Realm 1.2.0, the way to force a refresh would be the following:

public class RealmRefresh {
    public static void refreshRealm(Realm realm) {
        Message message = Message.obtain();
        msg.what = HandlerControllerConstants.LOCAL_COMMIT;
        realm.handlerController.handleMessage(msg);
    }
}

How can I refresh realm instance if that RealmRefresh does not exist and I cannot access to the private attribute handlerController???

You shouldn't need to manually call refresh(). Instead rely on our change listeners or open/close the Realm as appropriate. Generally if you are in a position where you think you want to call refresh(). It is most likely because you don't control the flow of your code as well as it could be.

What is your use case?

@jcmontesmartos RealmRefresh doesn't exist, and the code snippet above assumes that you create this class manually in the package io.realm;

@cmelchior I use realm just to cache data from server and I rely on the information that realm has. So after fetching data and storing in realm using jobs, that use another thread different to the main one, when I want to refresh the information in the UI, I don't get the latest data. Using method refresh(), it worked with v. 0.87.4

@Zhuinden Ok, got it! thanks ;-)

Hi, any updates for realm 3.X.X? It changed again.

On another note. When I acquire a realm with Realm.getDefaultInstance() on a background Thread where I already have an active realm. Is this newly acquired instance guaranteed to be refreshed and up to date?

@markini you can force a refresh as specified here

Was this page helpful?
0 / 5 - 0 ratings