Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.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
Android 使用匕首从错误线程访问领域_Android_Realm_Mvp_Dagger 2 - Fatal编程技术网

Android 使用匕首从错误线程访问领域

Android 使用匕首从错误线程访问领域,android,realm,mvp,dagger-2,Android,Realm,Mvp,Dagger 2,我目前正在一个简单的项目中学习Dagger、RxJava、Realm和MVP 基本上,这个应用程序可以做的是,它可以查看、添加、删除和更新数据库中的数据,我使用的是Realm 我决定遵循MVP体系结构和应用存储库模式,并在后端层进行数据操作 作为额外的学习,我在体系结构中为依赖注入添加了匕首 在此之前,我开发了一个应用程序,没有应用MVP或存储库模式,甚至没有考虑Dagger和RxJava。所有这些看起来都工作得很好,没有任何来自Realm线程系统的错误。也许是因为我把所有的东西都放在一节课上了

我目前正在一个简单的项目中学习Dagger、RxJava、Realm和MVP

基本上,这个应用程序可以做的是,它可以查看、添加、删除和更新数据库中的数据,我使用的是Realm

我决定遵循MVP体系结构和应用存储库模式,并在后端层进行数据操作

作为额外的学习,我在体系结构中为依赖注入添加了匕首

在此之前,我开发了一个应用程序,没有应用MVP或存储库模式,甚至没有考虑Dagger和RxJava。所有这些看起来都工作得很好,没有任何来自Realm线程系统的错误。也许是因为我把所有的东西都放在一节课上了

因此,现在我正在远离这种方法,在新方法中实现它时遇到了困难,我认为这种方法更松散耦合,如果正确实现,应该会更好


介绍够了,让我们回到主题上来

我现在面临的问题是Realm总是给我这个错误:

引发异常:从错误线程访问域

我怀疑我的匕首图没有得到正确的管理(特别是在提供领域实例时),因此每当我查询数据时,它都会给我错误

所以,我的匕首部件看起来像这样:

@Singleton
@Component(modules = {ContextModule.class, RepositoryModule.class, PresenterModule.class})
public interface AppComponent {

    /* Inejct application */
    void inject(FourdoApp fourdoApp);

    /* Realm Helper */
    void inject(DatabaseRealm databaseRealm);

    /* Activity */
    void inject(MainActivity mainActivity);
    void inject(TaskDetailActivity taskDetailActivity);

    /* Presenter*/
    void inject(MainPresenter mainPresenter);
    void inject(TaskDetailPresenter taskDetailPresenter);

    /* Model repository*/
    void inject(TaskRepositoryImpl taskRepository);

}
内部
RepositoryModule.class

@Module
public class RepositoryModule {

    @Provides
    @Singleton
    Repository<Task> provideTaskRepository() {
        return new TaskRepositoryImpl();
    }

    // Here I provide DatabaseRealm class instance

    @Provides
    @Singleton
    public DatabaseRealm provideDatabaseRealm() {
        return new DatabaseRealm();
    }

}
在MainPresenter内部,我注入了Repository接口,从
TaskRepositoryImpl
请求数据库中的真实数据

public class MainPresenter extends BasePresenter<MainContract.View> implements MainContract.Presenter {

    @Inject
    Repository<Task> taskRepository;

    public MainPresenter() {
        Injector.getAppComponent().inject(this);
    }

    @Override
    public void onRequestData() {
        requestData();
    }

    private void requestData() {

        taskRepository.findAll()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .map(this::mapToStringList)
                .subscribe(new Observer<List<String>>() {

                    @Override
                    public void onNext(List<String> strings) { // Error in this line
                        if (strings.size() > 0) {
                            mView.onRequestDataSuccess(strings);
                        } else {
                            mView.showEmpty();
                        }
                    }
                });
    }
}
DatabaseRealm的代码如下:

public class DatabaseRealm {
    @Inject
    Context context;

    RealmConfiguration realmConfiguration;

    public DatabaseRealm() {
        Injector.getAppComponent().inject(this);
    }

    public void setup() {
        if (realmConfiguration == null) {
            Realm.init(context);
            realmConfiguration = new RealmConfiguration.Builder()
                    .deleteRealmIfMigrationNeeded()
                    .build();
            Realm.setDefaultConfiguration(realmConfiguration);
        } else {
            throw new IllegalStateException("Realm already configured");
        }
    }

    public Realm getRealmInstance() {
        return Realm.getDefaultInstance();
    }

    public <T extends RealmObject> T add(T model) {
        Realm realm = getRealmInstance();
        realm.beginTransaction();
        realm.copyToRealm(model);
        realm.commitTransaction();
        return model;
    }

    public <T extends RealmObject> T update(T model) {
        Realm realm = getRealmInstance();
        realm.beginTransaction();
        realm.copyToRealmOrUpdate(model);
        realm.commitTransaction();
        return model;
    }

    public <T extends RealmObject> T remove(T model) {
        Realm realm = getRealmInstance();
        realm.beginTransaction();
        realm.copyToRealm(model);
        realm.deleteAll();
        realm.commitTransaction();
        return model;
    }

    public <T extends RealmObject> List<T> findAll(Class<T> clazz) {
        return getRealmInstance().where(clazz).findAll();
    }

    public void close() {
        getRealmInstance().close();
    }
}
公共类数据库领域{
@注入
语境;
RealmConfiguration RealmConfiguration;
公共数据库领域(){
Injector.getAppComponent().Injector(此);
}
公共作废设置(){
if(realmConfiguration==null){
Realm.init(上下文);
realmConfiguration=newrealmconfiguration.Builder()
.DeleteRealMifMigrationRequired()
.build();
Realm.setDefaultConfiguration(realmConfiguration);
}否则{
抛出新的IllegalStateException(“领域已配置”);
}
}
公共领域getRealMinInstance(){
返回Realm.getDefaultInstance();
}
公共T添加(T模型){
realmrealm=getRealmInstance();
realm.beginTransaction();
realm.copyToRealm(模型);
realm.commitTransaction();
收益模型;
}
公共T更新(T模型){
realmrealm=getRealmInstance();
realm.beginTransaction();
realm.copyToRealmOrUpdate(模型);
realm.commitTransaction();
收益模型;
}
公共T删除(T型){
realmrealm=getRealmInstance();
realm.beginTransaction();
realm.copyToRealm(模型);
realm.deleteAll();
realm.commitTransaction();
收益模型;
}
公共列表findAll(类别分类){
返回getRealmInstance().where(clazz.findAll();
}
公众假期结束(){
getRealMinInstance().close();
}
}
这个有缺陷代码的完整源代码是正确的

我想澄清一下,我对Dagger中使用的领域实例了解有限

我遵循了Realm的存储库设计模式,但它不包括Dagger的依赖项注入


有人能告诉我为什么它总是告诉我从错误的线程调用Realm吗?

您只需要在
应用程序
类中设置
RealmConfigration
一次,并使用
Realm.getDeafultInstance()
方法访问Realm数据库

使用Dagger,您只需要在构造函数中传递领域实例

你可以跟着这个走,用叉子叉


这与您在此处发布的代码不完全相同。但它可能有助于更好地理解使用MVP、RxJava和Realm的dagger。我认为您会出现此错误,因为:

@Override
public Observable<List<Task>> findAll() {
    return Observable.create(subscriber -> {
        try {
            List<Task> models = databaseRealm.findAll(Task.class);

            subscriber.onNext(models);
            subscriber.onComplete();
        } catch (Exception e) {
            subscriber.onError(e);
        }
    });
}

我没用匕首工作过。但我猜问题是因为“领域无法跨线程访问对象”。我认为这是王国的一个劣势。请看一下这一点。希望能有所帮助。你是对的。我只需要在应用程序中实例化一次领域。然后使用Dagger提供默认实例。谢谢
public class DatabaseRealm {
    @Inject
    Context context;

    RealmConfiguration realmConfiguration;

    public DatabaseRealm() {
        Injector.getAppComponent().inject(this);
    }

    public void setup() {
        if (realmConfiguration == null) {
            Realm.init(context);
            realmConfiguration = new RealmConfiguration.Builder()
                    .deleteRealmIfMigrationNeeded()
                    .build();
            Realm.setDefaultConfiguration(realmConfiguration);
        } else {
            throw new IllegalStateException("Realm already configured");
        }
    }

    public Realm getRealmInstance() {
        return Realm.getDefaultInstance();
    }

    public <T extends RealmObject> T add(T model) {
        Realm realm = getRealmInstance();
        realm.beginTransaction();
        realm.copyToRealm(model);
        realm.commitTransaction();
        return model;
    }

    public <T extends RealmObject> T update(T model) {
        Realm realm = getRealmInstance();
        realm.beginTransaction();
        realm.copyToRealmOrUpdate(model);
        realm.commitTransaction();
        return model;
    }

    public <T extends RealmObject> T remove(T model) {
        Realm realm = getRealmInstance();
        realm.beginTransaction();
        realm.copyToRealm(model);
        realm.deleteAll();
        realm.commitTransaction();
        return model;
    }

    public <T extends RealmObject> List<T> findAll(Class<T> clazz) {
        return getRealmInstance().where(clazz).findAll();
    }

    public void close() {
        getRealmInstance().close();
    }
}
@Override
public Observable<List<Task>> findAll() {
    return Observable.create(subscriber -> {
        try {
            List<Task> models = databaseRealm.findAll(Task.class);

            subscriber.onNext(models);
            subscriber.onComplete();
        } catch (Exception e) {
            subscriber.onError(e);
        }
    });
}
@Override
public Observable<List<Task>> findAll() {
    return Observable.create(subscriber -> {
        try {
            Realm realm = getRealmInstance();
            List<Task> models = realm.findAll(Task.class);

            subscriber.onNext(models);
            subscriber.onComplete();
        } catch (Exception e) {
            subscriber.onError(e);
        }
    });
}