私が読んだことからメインスレッドでデータベースクエリを発行することはできません(メインスレッドで遅延を引き起こす可能性があります)だから、UIのテキストビューを更新しようとしていると想像してくださいいくつかのデータがどのようにコールバックを取得するメインスレッド。例を示しましょう。ビジネスモデルデータをEventsというオブジェクトに保存したいと想像してください。したがって、EventDaoオブジェクトがあります。
以下にこのDAOオブジェクトがあると想像してください。
@Dao
public interface EventDao {
@Query("SELECT * FROM " + Event.TABLE_NAME + " WHERE " + Event.DATE_FIELD + " > :minDate" limit 1)
LiveData<List<Event>> getEvent(LocalDateTime minDate);
@Insert(onConflict = REPLACE)
void addEvent(Event event);
@Delete
void deleteEvent(Event event);
@Update(onConflict = REPLACE)
void updateEvent(Event event);
}
そして今、いくつかのアクティビティでテキストビューがあり、その値を更新したいのでこれを行います:
myTextView.setText(EventDao.getEvent(someDate));/*i think this is illegal as im trying to call room dao on mainthread, therefore how is this done correctly ? would i need to show a spinner while it updates ?*/
フェッチはメインスレッドから行われているため、このように呼び出してスムーズな更新を期待できるとは思わない。ここで最善のアプローチは何ですか?
いくつかの追加情報:モデルデータベースの情報をメモリに静的に保持するのではなく、取得するためのメカニズムとしてルームデータベースを使用したかった。そのため、残りのサービスを介してダウンロードした後、dbを介してローカルでモデルを使用できます。
[〜#〜] update [〜#〜]:したがって、ライブデータを返すので、これを行うことができます:
eventDao = eventDatabase.eventDao();
eventDao.getEvent().observe(this, event -> {
myTextView.setText(event.get(0));
});
そして、それは非常に小さなものに有効です。しかし、私のデータベースには100万のアイテムがあると想像してください。その後、この呼び出しを行うと、データの取得に遅延が生じます。これが最初に呼び出されると、遅延があることがユーザーに表示されます。これを避ける方法は?明確にするために、ライブデータが不要な場合があります。ビューを一度更新するだけです。これを行う方法を知る必要がありますか? liveDataがない場合でも。
クエリを同期的に実行し、データセットの更新の通知を受信しない場合は、戻り値をLiveDataオブジェクトにラップしないでください。 Googleのサンプルコードをご覧ください。
loadProductSync()
here を見てください
非同期をオフにして同期アクセスを許可する方法があります。
データベースを構築するときに使用できます: allowMainThreadQueries()
また、メモリ内での使用: Room.inMemoryDatabaseBuilder()
推奨されていませんが。そのため、超高速アクセスが必要な場合は、最終的にメモリ内データベースとメインスレッドアクセスを使用できます。それは私のデータの大きさによると思いますが、この場合は非常に小さいです。
しかし、コールバックを使用したい場合.... rxJavaを使用すると、データベースに保存したい国のリスト用に作成されたものがあります:
public Observable<CountryModel> queryCountryInfoFor(final String isoCode) {
return Observable.fromCallable(new Callable<CountryModel>() {
@Override
public CountryModel call() throws Exception {
return db.countriesDao().getCountry(isoCode);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
その後、この関数にサブスクライバを簡単に追加して、Rxjavaでコールバックを取得できます。
Bohsenのように、クエリにlivedataを同期的に使用することをお勧めします。しかし、特別な場合には、ロジックに基づいて非同期操作を行いたいことがあります。以下の例では、親コメントの子コメントを取得する必要があります。 DBですでに利用可能ですが、recyclerviewアダプタのparent_idに基づいて取得する必要があります。これを行うには、AsyncTaskのreturnコンセプトを使用して結果を取得しました。 (コトリンに戻る)
リポジトリクラス
fun getChildDiscussions(parentId: Int): List<DiscussionEntity>? {
return GetChildDiscussionAsyncTask(discussionDao).execute(parentId).get()
}
private class GetChildDiscussionAsyncTask constructor(private val discussionDao: DiscussionDao?): AsyncTask<Int, Void, List<DiscussionEntity>?>() {
override fun doInBackground(vararg params: Int?): List<DiscussionEntity>? {
return discussionDao?.getChildDiscussionList(params[0]!!)
}
}
Daoクラス
@Query("SELECT * FROM discussion_table WHERE parent_id = :parentId")
fun getChildDiscussionList(parentId: Int): List<DiscussionEntity>?