2

I have problem working with realm.

findAll and findAllAsync doesnot return any data from realm.

I am updating realm object from main thread like this.

public void updatePhoto(final int ticketID) {
    realm.beginTransaction();
    RealmResults ticketPhotos =  realm.where(TicketPhoto.class).equalTo("TicketID", ticketID).findAll();`           
    for (TicketPhoto ticketPhoto : ticketPhotos) { 
        ticketPhoto.IsModified = true;
    }
    realm.commitTransaction(); 
} '$'

At same time one background service is running for every five minutes and keeps checking for any objects having IsModified flag as true. From my background service(IntentService), am using AsyncTask and in doInBackground, am trying to get those IsModified records and I assume realm should pick those records and update with my server. Used the below code to get data from realm.

public RealmResults getTicketPhotosToSave (){
    return realm.where(TicketPhoto.class)
           .equalTo("IsModified", true)
           .findAll(); 
}

When am still in the same Photo activity where I save photo to realm with IsModified flag as true, realm in background service is not picking those records. But when I destroy the app and just run it again, service is now picking those records. Am not sure if am doing something wrong here.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
sai
  • 97
  • 1
  • 10
  • Your background service is going to retain an older version of the Realm, and never get updated (because it is not associated with a looper that actually loops). Try running your service logic in a transaction. You're on a background thread, so use `findAll()`. (not async) – EpicPandaForce Sep 20 '16 at 19:00
  • I am using IntentService and calling wakefulcroadcastreciever for every 5 mins in which my tasks are running. I am instantiating their own Realm instance within each method where i am calling DB. – sai Sep 20 '16 at 19:51
  • Do you **close** the Realm instance? And even more importantly, do you by chance have `android:process=":remote"` specified? because realm below the latest snapshot, multi-process notifications are not yet supported – EpicPandaForce Sep 20 '16 at 20:10
  • Yes I am close its instance after saving into realm. And instantiating each time while getting from realm. – sai Sep 20 '16 at 20:40
  • I dint specified android:process=":remote" – sai Sep 20 '16 at 20:40

2 Answers2

1

Its working. thanks for your support

Now I understood that unless we are updating the data on same thread, no need to close realm. We need to close realm always when we need access to those changes in different thread . Since background thread always needs access to all objects, we have to close and open realm just before accessing data.

So before accessing/querying data, I am refreshing realm as @Zhuinden suggested ( realm not fetching data) and then realm.Close(). After this I am creating instance (realm = Realm.getDefaultInstance(); )

Community
  • 1
  • 1
sai
  • 97
  • 1
  • 10
  • Technically you need to close the Realm at the execution of a non-looper background thread because you're otherwise retaining old version of the Realm which is rather resource-intensive in case of many transactions if it exists for too long (unless your Realm instance is refreshed and therefore up to date, like the looper thread or this manual refresh I mentioned for non-loopers) – EpicPandaForce Sep 22 '16 at 21:40
0

I really hate recommending this solution, but you should force a refresh with the package-internal methods after Realm.getInstance() on your IntentService's Realm instance. This current solution I provide works for v1.2.0. Use it only on background threads (primarily your periodically running method).

package io.realm; // <---- this is important 

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

And then call

try {
    mRealm = Realm.getDefaultInstance();
    RealmRefresh.refreshRealm(mRealm);
    // do things
} finally {
    if(mRealm != null) {
        mRealm.close();
    }
}
Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428