我正在编写一些代码来将记录插入 Sqlite 数据库(如果表为空)。在插入任何数据之前,它会进行 Web 服务调用LoveToDo.basecampClient().fetchMe()
以返回一些数据。
我使用 SqlBrite 进行数据库访问,使用 Retrofit 进行 Web 访问。这是我的代码:
Observable.just(LoveToDo.briteDatabase())
.map(new Func1<BriteDatabase, Integer>() {
@Override
public Integer call(BriteDatabase briteDatabase) {
Cursor cursor = briteDatabase.query("SELECT * FROM Accounts");
try {
return cursor.getCount();
} finally {
cursor.close();
}
}
})
.flatMap(new Func1<Integer, Observable<Person>>() {
@Override
public Observable<Person> call(Integer count) {
if ( count == 0 ) {
return LoveToDo.basecampClient().fetchMe();
}
return null;
}
})
.map(new Func1<Person, Boolean>() {
@Override
public Boolean call(Person person) {
if ( person == null ) return false;
BriteDatabase database = LoveToDo.briteDatabase();
long count = database.insert(Account.TABLE, new Account.Builder()
.accountId(Settings.accountId)
.userName(Settings.userName)
.password(Settings.password)
.agent(Settings.agent)
.personId(person.id)
.build()
);
return count > 0;
}
})
.subscribeOn(Schedulers.io())
.observeOn( Schedulers.io() )
.subscribe();
不用说,我不认为这是很棒的代码。我想做的是找出如何将这段代码转换成好的东西。因此,让我们使用它并挑选它的可怕之处。
首先,我是否应该将数据库和 Web 服务调用操作结合在一个操作员中。例如:
Observable.just(LoveToDo.briteDatabase())
.flatMap(new Func1<BriteDatabase, Observable<Person>>() {
@Override
public Observable<Person> call(BriteDatabase briteDatabase) {
Cursor cursor = briteDatabase.query("SELECT * FROM Accounts");
int count;
try {
count = cursor.getCount();
} finally {
cursor.close();
}
if ( count == 0 ) {
return LoveToDo.basecampClient().fetchMe();
}
return null;
}
})
.map(new Func1<Person, Boolean>() {
@Override
public Boolean call(Person person) {
if ( person == null ) return false;
BriteDatabase database = LoveToDo.briteDatabase();
long count = database.insert(Account.TABLE, new Account.Builder()
.accountId(Settings.accountId)
.userName(Settings.userName)
.password(Settings.password)
.agent(Settings.agent)
.personId(person.id)
.build()
);
return count > 0;
}
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe();
或者是否有充分的理由将此类操作隔离在链中?
让我烦恼的第二件事是这是一个后台操作 - 不会因为这段代码而直接更新用户界面。这就是为什么有一个无参数的subscribe()
函数调用。但是当出现异常时会发生什么?这是否意味着我必须执行以下操作?
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
// Do nothing
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
// Do something with the exception
}
});
顺便说一句,我需要将subscribeOn
whenobserveOn
设置为后台线程吗?
第三,链由 SqlBrite 观察者启动。在链的后面,我再次需要 SqlBrite,所以我使用 singleton 访问它LoveToDo.briteDatabase()
。这是一个坏主意吗?有一个更好的方法吗?
最后,有没有办法上break;
链?如果我可以放弃我正在做的事情而不是在每一步检查丢失的数据,那就太好了