Passing realm instance as method parameter to pojo


(Paolo) #1

Hi all,

I’m working with Realm 6.0.1 on Android (Java). I’m fighting with large Realm file size & related logcat warning:

W/REALM_JAVA: Remember to call close() on all Realm instances. Realm /data/data/it.manutencooprivate.appmanutentorifornitori/files/default.realm is being finalized without being closed, this can lead to running out of native memory.

I’m refactoring my code applying good practices in handling Realm instances, as suggested in documentation, so in every activity’s onCreate() i got an instance with this.realm = Realm.getDefaultInstance(); and perform the this.realm.close() in onDestroy(). In threads other than UI (AsyncTask and WokManger) I always use the try-with-resources statement.

My question is: once I have got the Realm instance for the current thread with the above statements, can I use it as a parameter to be passed to methods of other plain Java classes I use inside my Activities or Threads? This is an example:

public class OrderListActivity extends AppCompatActivity {

    private Realm realm;
    private MyClassPlayingWithRealm mPojo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_cluster);

        this.realm = Realm.getDefaultInstance();
        mPojo = new MyClassPlayingWithRealm(this.realm);
        mPojo.doSomethingWithRealm(new Object());
        MyStaticClassPlayingWithRealm.doSomethingStaticWithRealm(this.realm, new Object()); 

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(LOG_TAG, "onDestroy");
        this.realm.close();
    }

}

public class MyClassPlayingWithRealm  {
    
    Realm pojoRealm;

    public MyClassPlayingWithRealm(Realm realm) {
        this.pojoRealm = realm;
    }

    public void doSomethingWithRealm (Object oby) {
        this.pojoRealm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.copyToRealmOrUpdate(obj);
            }
        });
    }

}

public class MyStaticClassPlayingWithRealm  {
    
    public static void doSomethingStaticWithRealm (Realm realm, Object obj) {
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.copyToRealmOrUpdate(obj);
            }
        });
    }

}

Is this a safe (I don’t mean thread safe, I know realm instance can’t be shared between threads) way to handle realm instance inside the same thread? Or is better to use Realm.getDefaultInstance() inside every class with the issue of taking care to close it?

Thanks.
Paolo


(Paolo) #2

As per this comment on this inspiring Medium post by @zhuinden it seems to be a good idea to pass Realm instance to methods.