2015-05-19 18 views
8

Tôi đang xử lý sự cố này trên Android:Truy cập giới hạn từ chuỗi không chính xác Android

Truy cập từ chủ đề không chính xác. Các đối tượng realm chỉ có thể được truy cập trên luồng mà chúng tạo ra.

Tôi muốn sử dụng Realm trong RemoteViewsFactory tôi với

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 
    } 

}

... Cuộc gọi này không thành công! Tại sao ?

tôi lấy dữ liệu của tôi như thế này trong lớp học của tôi:

public void onDataSetChanged() { 
     Realm realm = Realm.getInstance(RemoteViewsX.this.ctx); 
     this.results = realm.where(Model.class).findAll(); 
} 

tôi gọi remoteFactory của tôi như thế này:

public class ScrollWidgetService extends RemoteViewsService { 
    @Override 
    public RemoteViewsFactory onGetViewFactory(Intent intent) { 
     return new RemoteViewsX (getApplicationContext()); 
    } 
} 

Bất kỳ ý tưởng?

+1

Tôi không quen với RemoteViewsService, nhưng dường như phương thức '' 'onDataSetChanged''' của bạn được gọi từ một chuỗi khác với phương thức' '' getViewAt''' của bạn. Tôi không chắc chắn nếu điều này là do cách hoạt động của RemoteViewsService hoặc mã của bạn. –

+0

Ok thx, làm thế nào tôi có thể sửa nó? – manua27

+0

Để phá vỡ giới hạn lĩnh vực đó, bạn có thể tham khảo bài đăng này http://stackoverflow.com/questions/26602258/how-to-achieve-the-following-in-realm-for-android/32607241#32607241. nó cho thấy loại thực hiện wrapper để giải phóng ứng dụng của bạn khỏi truy cập Realm từ ngoại lệ thread không chính xác –

Trả lời

2

Nếu vấn đề là do gọi onDataSetChangedgetViewAt từ thread khác, bạn có thể buộc họ phải sử dụng cùng một sợi, tạo của riêng bạn HandlerThread như thế này:

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]; 
} 

tôi sao chép Lock lớp từ trang này: http://tutorials.jenkov.com/java-concurrency/locks.html
Đừng quên quit chuỗi xử lý khi công việc của bạn được thực hiện.

+0

Ý của bạn là gì liên quan đến "bỏ thuốc lá"? – manua27

+0

Tôi có nghĩa là phương pháp này: http://developer.android.com/reference/android/os/HandlerThread.html#quit() Chủ đề không dừng trừ khi bạn gọi phương thức. – usp

0

Tôi dựa trên RxJava, vì vậy tôi làm điều này trong một lĩnh vực. Tôi sao chép từng mục vì chúng là một phần của chủ đề chính và điều đó lộn xộn khi tôi làm việc trong một chủ đề khác như màn hình chính của tiện ích con.

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

     for(Dog dog: mainThreadDogs){ 
      thisThreadDogs.add(ModelUtil.cloneDog(dog)); 
     }  
}); 
Các vấn đề liên quan