Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 跨所有线程使用领域_Java_Android_Realm_Kotlin - Fatal编程技术网

Java 跨所有线程使用领域

Java 跨所有线程使用领域,java,android,realm,kotlin,Java,Android,Realm,Kotlin,我有用于CRUD操作的DBManager类,我想在整个应用程序中使用它,我知道领域对象只能在创建它们的线程上访问,因此我无法在线程内使用DBManager类方法等等 我想要的是从服务内部运行的线程调用在DBManager内部声明的updateUploadingFileStatus方法 这是我的DBManager类 object DbManager { private val realm: Realm by lazy { Realm.getDefaultInstance() } fun save

我有用于CRUD操作的DBManager类,我想在整个应用程序中使用它,我知道领域对象只能在创建它们的线程上访问,因此我无法在线程内使用DBManager类方法等等

我想要的是从服务内部运行的线程调用在DBManager内部声明的updateUploadingFileStatus方法

这是我的DBManager类

object DbManager {
private val realm: Realm by lazy { Realm.getDefaultInstance() }

fun saveOrRemoveUploadFile(filePath: String, save: Boolean){
    val model = getUploadModelByFilePath(filePath)
    realm.executeTransaction {
        model.markedForUpload = save
        realm.insertOrUpdate(model)
    }
}

fun updateUploadingFileStatus(filePath: String, uploaded: Boolean){
    val model = getUploadModelByFilePath(filePath)
    realm.executeTransaction {
        model.uploadedStatus = uploaded
    }
}

fun getFilesForUpload() : List<UploadModel> {
    return realm
            .where(UploadModel::class.java)
            .equalTo("markedForUpload",true)
            .equalTo("uploadedStatus",false)
            .findAll()
}

fun getUploadModelByFilePath(filePath: String) : UploadModel {
    return realm.where(UploadModel::class.java).equalTo("filePath",filePath).findFirst() ?: UploadModel(filePath)
}

}
对象数据库管理器{ private val realm:lazy的realm{realm.getDefaultInstance()} fun saveOrRemoveUploadFile(文件路径:字符串,保存:布尔值){ val model=getUploadModelByFilePath(文件路径) realm.executeTransaction{ model.markedForUpload=保存 realm.insertOrUpdate(模型) } } fun updateUploadingFileStatus(文件路径:字符串,上载:布尔值){ val model=getUploadModelByFilePath(文件路径) realm.executeTransaction{ model.uploadedStatus=已上载 } } fun getFilesForUpload():列表{ 返回域 .where(UploadModel::class.java) .equalTo(“markedForUpload”,true) .equalTo(“uploadedStatus”,false) .findAll() } fun getUploadModelByFilePath(文件路径:字符串):UploadModel{ 返回realm.where(UploadModel::class.java).equalTo(“filePath”,filePath).findFirst()?:UploadModel(filePath) } }
从另一个线程调用此方法会从错误的线程引发对java.lang.IllegalStateException域的访问。如何解决此问题?这样做的好方式是什么?

如下更改功能代码:

 public void updateUploadingFileStatus(final String filePath, final Boolean uploaded) {
        mRealm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                UploadModel model = getUploadModelByFilePath(filePath);
                model.uploadedStatus = uploaded;
            }
        });
    }

很久以前,我通过使用一个新事务解决了这个问题。我还使用了一个单例类来访问RealmDB,并在来自网络的响应处理程序中调用了这个函数。这应该是可行的。

我知道这不是一个好主意,但是你的DbManager应该是一个单线程,这样你就可以跨每个线程访问同一个域,如果它是一个全局单线程,在哪里关闭领域?DBManager的每个方法调用都会自动关闭领域。您需要在每个方法中创建领域实例。通过在构造函数中使用它,它将在创建它的任何线程上第一次创建,但是如果从另一个线程调用,您的方法将无法工作。但要小心,如果这样做,你也要再次关闭它们。否则,您将泄漏后台线程上的实例,这非常糟糕。谢谢,但是您的代码和我的代码没有区别,只是您的事务是异步的。您是否在realm.executeTransaction()函数中隐式使用新事务?注意:您使用了Java标记,但那不是Java。是的,因为一切都是一样的,这是Kotlin。这很奇怪,因为使用一个新的Transaction force领域来使用一个新的领域实例,该实例是在调用该方法时创建的。所以你不是从另一个线程访问这个领域。