来自错误线程的领域访问 Android
Realm access from incorrect thread Android
我正在 Android 处理这个问题:
来自错误线程的领域访问。领域对象只能在创建它们的线程上访问。
我想在我的 RemoteViewsFactory 中使用 Realm
public class RemoteViewsX implements RemoteViewsFactory {
public RemoteViews getViewAt(int paramInt) {
if (this.results != null && this.results.size() != 0 && this.results.get(paramInt) != null) {
//FAILED HERE
}
}
...
本次调用失败!为什么?
我在 class:
中这样获取数据
public void onDataSetChanged() {
Realm realm = Realm.getInstance(RemoteViewsX.this.ctx);
this.results = realm.where(Model.class).findAll();
}
我这样调用我的 remoteFactory :
public class ScrollWidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new RemoteViewsX (getApplicationContext());
}
}
有什么想法吗?
如果问题是由从另一个线程调用 onDataSetChanged
和 getViewAt
引起的,您可以强制它们使用相同的线程,创建您自己的 HandlerThread
,如下所示:
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];
}
我从这个页面复制了Lock
class:http://tutorials.jenkov.com/java-concurrency/locks.html
完成任务后,不要忘记 quit
处理程序线程。
我是基于RxJava的,所以我是在realm里面做的。我克隆了每个项目,因为它们是主线程的一部分,当我在另一个线程(如小部件主屏幕)中工作时,这会搞砸。
myRealm.where( Dog.class ).findAllAsync().subscribe( mainThreadDogs->{
thisThreadDogs.clear();
for( Dog dog: mainThreadDogs ){
thisThreadDogs.add( ModelUtil.cloneDog( dog ) );
}
});
我正在 Android 处理这个问题:
来自错误线程的领域访问。领域对象只能在创建它们的线程上访问。
我想在我的 RemoteViewsFactory 中使用 Realm
public class RemoteViewsX implements RemoteViewsFactory {
public RemoteViews getViewAt(int paramInt) {
if (this.results != null && this.results.size() != 0 && this.results.get(paramInt) != null) {
//FAILED HERE
}
}
... 本次调用失败!为什么?
我在 class:
中这样获取数据public void onDataSetChanged() {
Realm realm = Realm.getInstance(RemoteViewsX.this.ctx);
this.results = realm.where(Model.class).findAll();
}
我这样调用我的 remoteFactory :
public class ScrollWidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new RemoteViewsX (getApplicationContext());
}
}
有什么想法吗?
如果问题是由从另一个线程调用 onDataSetChanged
和 getViewAt
引起的,您可以强制它们使用相同的线程,创建您自己的 HandlerThread
,如下所示:
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];
}
我从这个页面复制了Lock
class:http://tutorials.jenkov.com/java-concurrency/locks.html
完成任务后,不要忘记 quit
处理程序线程。
我是基于RxJava的,所以我是在realm里面做的。我克隆了每个项目,因为它们是主线程的一部分,当我在另一个线程(如小部件主屏幕)中工作时,这会搞砸。
myRealm.where( Dog.class ).findAllAsync().subscribe( mainThreadDogs->{
thisThreadDogs.clear();
for( Dog dog: mainThreadDogs ){
thisThreadDogs.add( ModelUtil.cloneDog( dog ) );
}
});