2016-08-04 55 views
2

在我的应用程序中,我读取了保存在手机上的联系人,这可能需要很长时间,然后我把它放在Thread嵌套,我使用Realm,但我得到这个错误:Android我怎样才能在线程上使用Realm

Realm access from incorrect thread. 
Realm objects can only be accessed on the thread they were created. 

而我的解决方案不解决这个问题,比如:

new Handler().post(new Runnable() { 
    @Override 
    public void run() { 
     realm.executeTransaction(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 
      } 
     }); 
    } 
}); 

OR

new Handler(getMainLooper()).post(new Runnable() { 
    @Override 
    public void run() { 
     realm.executeTransaction(new Realm.Transaction() { 
      @Override 
      public void execute(Realm realm) { 
      } 
     });    
    } 
}); 

嵌套线程,

回答

3

您需要在给定线程上试图使用Realm实例的实例。

new Handler().post(new Runnable() { 
    @Override 
    public void run() { 
     Realm realm = null; 
     try { 
      realm = Realm.getDefaultInstance(); 
      realm.executeTransaction(new Realm.Transaction() { 
       @Override 
       public void execute(Realm realm) { 
       } 
      }); 
     } finally { 
      if(realm != null) { 
       realm.close(); 
      } 
     } 
    } 
}); 

尽管您不应该在UI线程上进行同步写入。如果您在UI线程上编写,请使用异步事务。

new Handler().post(new Runnable() { 
    @Override 
    public void run() { 
      final Realm realm = Realm.getDefaultInstance(); 
      realm.executeTransactionAsync(new Realm.Transaction() { 
       @Override 
       public void execute(Realm realm) { 
       } 
      }, 
      new Realm.Transaction.OnSuccess() { 
       @Override 
       public void onSuccess() { 
        realm.close(); 
       } 
      }, 
      new Realm.Transaction.OnError() { 
       @Override 
       public void onError(Throwable e) { 
        realm.close(); 
       } 
      }); 
    } 
}); 
+0

您对我的博文的回答非常有用,比最新接受的博文更好,非常感谢 –

+0

为什么我会在此答案中做线程跳转?这很奇怪。 – EpicPandaForce

1

问题不在于你在另一个线程中使用Realm,问题是你在另一个线程中使用了真实中的instance。通常这是一个简单的修复,类似这样的:

Realm realmForThisThread = Realm.getDefaultInstance(); 
realmForThisThread.executeTransaction(new Realm.Transaction() { 
    @Override 
    public void execute(Realm realm) { 
    } 
} 
... 
realmForThisThread.close(); 
+0

正确。一个线程需要它自己的Realm实例。但是,当你完成时,不要忘记关闭实例! –