在使用Room存储单词的字典应用程序中,我有一个带有TextField的片段。
当用户在TextField中输入一个单词时,我提取文本并将其发送给JobIntentService,然后它在自己的线程上同步调用DAO方法:
@Dao
public interface MyDao {
@Query("SELECT 1 FROM dictionary WHERE word = :word")
int findWord(String word);
}
最后,JobIntentService通过LocalBroadcastManager将结果发送给宿主活动,该活动调用片段上的公共方法。
这条路径是可行的,但是您可以看到它非常长,我必须编写很多样板代码来实现它。
some of my fragments
因此,我尝试将此片段也转换为使用LiveData,将方法的签名更改为:
@Dao
public interface MyDao {
@Query("SELECT 1 FROM dictionary WHERE word = :word")
LiveData<Integer> findWord(String word);
}
从我的片段中调用它:
public class MyFragment extends Fragment {
private static final Pattern PATTERN = Pattern.compile("([A-Z]{2,})");
private LiveData<Integer> mLiveData;
private EditText mInputText;
private CheckedTextView mResultText;
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
...
mInputText.addTextChangedListener(new TextWatcher() {
...
@Override
public void afterTextChanged(Editable s) {
String word = mInputText.getText().toString().trim().toUpperCase();
if (PATTERN.matcher(word).matches()) {
mLiveData = MyDatabase.getInstance(getContext()).myDao().findWord(word);
} else {
mResultText.setChecked(false);
}
}
});
mLiveData.observe(this, found -> {
if (found != null && found == 1) {
mResultText.setChecked(true);
} else {
mResultText.setChecked(false);
}
});
return view;
}
当然,上述方法在NPE中失败了,因为
mLiveData
为空。
但是当单词参数
findWord(word)
正在改变?