web-dev-qa-db-ja.com

android-コンテンツプロバイダーのないCursorLoaderとSQLite

私はこれが議論されていることを知っていますが、問題の現在の状態について尋ねたいと思いました。 sqliteデータベースに関連してCursorLoaderを使用するには、ContentProviderを作成する必要がありますか?

見つけた

ContentProviderなしのCursorLoaderの使用

Emmbyがコメントしたように、私がまだ望んでいたものを正確に見ます

  • ユーザーは、1つの制限に注意する必要があります。これは、データの変更時に更新するメカニズムがないことです(ローダーが行うはずです)

別の解決策が言及されています

https://github.com/commonsguy/cwac-loaderex

まだいくつかの欠点が指摘されています

  • ただし、自動再クエリを使用するには、UIと更新プログラムに同じローダーを使用する必要があり、バックグラウンドサービスの使いやすさを制限します。

もちろん、LoaderManagerを使用する場合、それが導入されたすべての利点を取得する必要があります。したがって、私の質問は、コンテンツプロバイダーを実装しなくてもsqliteデータベースに関連してLoaderManagerを使用する方法があり、それでもすべての利点があるかどうかです。

ありがとう

54
dorjeduck

投稿で言及した2つの実装は、両方ともCursorLoaderexceptのすべての利点を提供します。変更。

私は最近これをよく見てきましたが、Android APIは現在、生のSQLiteDatabaseのみでこれを行う手段を提供していません。 ContentResolver#notifyChange()およびCursor#setNotificationUri()メソッドのみを提供します。これらのメソッドは、特定の通知Cursor)で登録されたすべてのUrisに通知するために使用されます。

とはいえ、現時点での選択肢は次のとおりです。

  1. コンテンツが変更されたときにSQLiteDatabaseから通知を受信できるオブザーバーを自分で実装し、これらの通知をアプリケーションの既存のすべてのLoadersにリレーすることができます。私はかなり大規模な )ブログ投稿 を書きましたLoadersを実装する方法についてこの挑戦に挑戦します。または...

  2. Mark MurphyのLoaderExライブラリを使用し、彼のライブラリが提供するAsyncTask操作のみを使用してデータベースの変更を行います。彼のタスクがLoaderを更新する理由は、挿入/更新/削除が実行された直後にonContentChangedLoaderを呼び出して、事実上Loaderコンテンツが変更され、データを更新する必要があること。

  3. ContentProviderとともにCursorLoaderを使用するだけで、ContentResolver#notifyChange()メソッドを使用して、コンテンツの変更が発生したことをCursorLoaderに通知できます。

私はより良い解決策を見つけようとしていますが、私が見つけた/実装したことがあれば、将来報告しますが、今のところはそうする必要があります。

66
Alex Lockwood

これが私のソリューションで、onCreateLoaderにあります

{
Uri u = Uri.parse("content://what_string_you_want");
return new CursorLoader(this, yourURI, projection, null, null, null) {
    private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();

    @Override
    public Cursor loadInBackground() {
        Cursor c = YOUR_DATABASE.doYourQuery(...);
        if (c != null) {
          // Ensure the cursor window is filled
           c.getCount();
           c.registerContentObserver(mObserver);
        }

        c.setNotificationUri(getContext().getContentResolver(), getUri());
        return c;
    }
};
}

DBを変更するコードの後に​​、以下を追加します

 getContentResolver().notifyChange(
            Uri.parse("content://same_with_first_string"), null);
2
Dev Ngo