我有一个数据库表联系人,我想检查是否有一些电话号码的联系人。
@Query("SELECT * FROM contact WHERE phone_number = :number")
Flowable<Contact> findByPhoneNumber(int number);
我有RxJava 2 Composite一次性产品,上面有声明,以检查是否有电话号码联系人。
disposable.add(Db.with(context).getContactsDao().findByPhoneNumber(phoneNumber)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSubscriber<Contact>() {
@Override
public void onNext(final Contact contact) {
Log.d("TAG", "phone number fined");
Conversation conversation;
if(contact != null){
conversation = Db.with(context).getConversationsDao().findBySender(contact.getContactId());
if(conversation != null){
conversation.setUpdatedAt(Utils.getDateAndTimeNow());
saveConversation(contact, conversation, context, text, phoneNumber, false);
} else {
conversation = getConversation(contact, contact.getPhoneNumber());
saveConversation(contact, conversation, context, text, phoneNumber, true);
}
} else {
conversation = Db.with(context).getConversationsDao().findByPhone(phoneNumber);
if(conversation != null){
conversation.setUpdatedAt(Utils.getDateAndTimeNow());
saveConversation(contact, conversation, context, text, phoneNumber, false);
} else {
conversation = getConversation(contact, phoneNumber);
saveConversation(contact, conversation, context, text, phoneNumber, true);
}
}
}
@Override
public void onError(Throwable t) {
Log.d("TAG", "find phone number throwable");
Toast.makeText(context, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
@Override
public void onComplete() {
Log.d("TAG", "onComplete");
}
}));
如果查询可以找到具有所需电话号码的联系人,这是正常的,但如果有结果,它不会发生任何事情。
下面是我编写的两个测试用例,它们运行良好:
@RunWith(AndroidJUnit4.class)
public class ContactsTest {
private AppDatabase db;
@Rule
public InstantTaskExecutorRule instantTaskExecutorRule =
new InstantTaskExecutorRule();
@Before
public void initDb() throws Exception {
db = Room.inMemoryDatabaseBuilder(
InstrumentationRegistry.getContext(),
AppDatabase.class)
// allowing main thread queries, just for testing
.allowMainThreadQueries()
.build();
}
@After
public void close(){
db.close();
}
@Test
public void insertAndFindTest(){
final Contact contact = new Contact();
contact.setName("Test");
contact.setPhoneNumber(555);
db.contactsDao()
.insert(contact);
db.contactsDao().findByPhoneNumber(contact.getPhoneNumber())
.test()
.assertValue(new Predicate<Contact>() {
@Override
public boolean test(@NonNull Contact savedContact) throws Exception {
if(savedContact.getPhoneNumber() == contact.getPhoneNumber()){
return true;
}
return false;
}
});
}
@Test
public void findNoValues(){
db.contactsDao().findByPhoneNumber(333)
.test()
.assertNoValues();
}
}
我怎么能解决这个问题呢?
5条答案
按热度按时间zbdgwd5y1#
如here所述,在这种情况下可以使用
Maybe
或Single
:也许吧
以下是发生的情况:
单个
以下是一些场景:
在版本1.0.0-alpha 5中添加了此功能。
q5lcpyga2#
如果您只想使用实体一次,
Single
或Maybe
就足够了,但是如果您想观察查询是否更新,您可以使用Flowable
并将对象 Package 在List
中,这样当没有结果时,您将得到空列表,之后,当数据库更新时,您将得到另一个事件,该事件结果在列表中编码
我相信它在某些情况下是有用的。缺点是你必须访问
resultList.get(0)
这样的对象c7rzv4ha3#
当你在
Dao
类中使用Flowable
(也是LiveData
)作为返回值时,你的查询就不会停止发送数据,因为Room会监控表中的数据变化。此外,如果响应是可观察的数据类型(如Flowable或LiveData),则Room会监视查询中引用的所有表是否失效。
我不知道处理这种情况的最好方法是什么,但对我来说,一个很好的老
.timeout()
操作符是有效的。请看下面的测试和评论:uinbv5nw4#
我想你也可以用 Package 器来 Package Single。比如:
并像这样使用它:
其中
createAsyncSingle
:不要忘记使用IO线程。
unftdfkk5#
然后
如所述here
我觉得奇怪的是这种行为在官方的文件上却找不到