Realm access from incorrect thread Android

浪尽此生 提交于 2019-12-05 05:12:28

If the problem is caused by calling onDataSetChanged and getViewAt from another thread, you can force them to use the same thread, creating your own HandlerThread like this:

public class Lock {
    private boolean isLocked;

    public synchronized void lock() throws InterruptedException {
        isLocked = true;
        while (isLocked) {
            wait();
        }
    }

    public synchronized void unlock() {
        isLocked = false;
        notify();
    }
}

public class MyHandlerThread extends HandlerThread {
    private Handler mHandler;

    public MyHandlerThread() {
        super("MY_HANDLER_THREAD");
        start();
        mHandler = new Handler(getLooper());
    }

    public Handler getHandler() {
        return mHandler;
    }
}

public class RemoteViewsX implements RemoteViewsFactory {
    private MyHandlerThread mHandlerThread;
    ...
}

public void onDataSetChanged() {
    Lock lock = new Lock();
    mHandlerThread.getHandler().post(new Runnable() {
        @Override
        public void run() {
            Realm realm = Realm.getInstance(ctx);
            results = realm.where(Model.class).findAll();
            lock.unlock();
        }
    });
    lock.lock();
}

public RemoteViews getViewAt(int paramInt) {
    Lock lock = new Lock();
    final RemoteViews[] result = {null};
    mHandlerThread.getHandler().post(new Runnable() {
        @Override
        public void run() {
            // You can safely access results here.
            result[0] = new RemoteViews();
            lock.unlock();
        }
    });
    lock.lock();
    return result[0];
}

I copied Lock class from this page: http://tutorials.jenkov.com/java-concurrency/locks.html
Do not forget to quit the handler thread when your tasks are done.

I am based on RxJava, so I do this in a realm. I clone each item because they are part of the main thread and that messes up when I am working in another thread such a widget home screen.

myRealm.where( Dog.class ).findAllAsync().subscribe( mainThreadDogs->{
       thisThreadDogs.clear();

       for( Dog dog: mainThreadDogs ){
            thisThreadDogs.add( ModelUtil.cloneDog( dog ) ); 
       }    
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!