2016-08-07 10 views
1

Socket.IO接続を処理するために使用しているServiceクラス内のRealmインスタンスにアクセスするのに問題があります。私はこれのようにonStartCommandコールでRealmインスタンスを取得しています。サービスでRealmインスタンスに正しくアクセスするにはどうすればよいですか?

public class SocketService extends Service{ 
    Realm realmInstance; 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     realmInstance = Realm.getDefaultInstance(); 
    } 
} 

私はRealmにいくつかのデータを格納する必要があるイベントを受信すると、ソケットのイベントに結合するときに問題があるが、それは以外のスレッドにアクセスすることができないRealmオブジェクトを示す例外をスローそれが作成されたものです。

socket.on("register", new Emitter.Listener() { 
      @Override 
      public void call(Object... args) { 
       List<MyRealmObject> list = realmInstance.where(MyRealmObject.class).findAll(); 
      } 
     }); 

java.lang.IllegalStateException:間違ったスレッドからレルムへのアクセス。 レルムオブジェクトは、彼らだけが

Iのイベントを作成したスレッド上でアクセスすることができ、私は無駄にsocket.ioのCONNECTコール内でインスタンス化私のイベントの呼び出しのための別のインスタンスを作成してみました。

+0

https://realm.io/docs/java/latest/#threadingを参照してください。 'call()'は 'realmInstance'が作成された場所とは別のスレッドで実行されています。そのスレッドの専用インスタンスを取得するには、呼び出しメソッドで 'getDefaultInstance()'を呼び出す必要があります。インスタンスを使用した後でインスタンスを閉じることを忘れないでください。 – beeender

答えて

1

public int onStartCommand(Intent intent, int flags, int startId) {は、UIスレッドで実行されます。

public void call(Object... args) {は、バックグラウンドスレッドで実行されます。

これらは同じスレッドではありません。各スレッドは独自のRealmインスタンスを必要とします(スレッド上のRealmにアクセスする場合)。自動更新できないバックグラウンドスレッドでは、不要になったRealmインスタンスを閉じる必要があります。

socket.on("register", new Emitter.Listener() { 
     @Override 
     public void call(Object... args) { 
      try(Realm realm = Realm.getDefaultInstance()) { 
       List<MyRealmObject> list = realm.where(MyRealmObject.class).findAll(); 
      } // try-with-resources auto-close 
     } 
    }); 
関連する問題