11

SQLiteを操作するための独自のContentProvideの実装に関するこのチュートリアルを読んでいます。ContentProvider.queryには、私を困惑させることがいくつかあります。1つのテーブル(チュートリアルのtodoテーブル)に非常にハードコーディングされているように見えますが、おそらくImはそれを取得していませんか?ここで、別のテーブルをクエリしたい場合、たとえばnodoとすると、ContentProviderをどのように変更しますか?

queryBuilder.setTables(String inTables)にテーブル名を追加する必要がありますか?

CONTENT_TYPEとCONTENT_ITEM_TYPEはどうですか?テーブルごとに1つある必要がありますか?

TODO変数とTODO_ID変数、およびクエリメソッドのスイッチについてはどうでしょうか。

同じContentProviderで複数のテーブルをサポートするには、多くのif / switch条件が必要なようですが、これは正しい方法ですか、それとも間違ったパスにいますか?

ありがとう
Søren

4

3 に答える 3

27

ここで、別のテーブルをクエリしたい場合、たとえばnodoとすると、ContentProviderをどのように変更しますか?

別のテーブルを使用する場合と同様に、はデータソースを選択するUriため、新しいテーブルをクエリすると、新しいテーブルを追加する必要があります。Uri

他のテーブルのToDoにすでに存在する、基本的にすべてのハードコードされた値を追加することになります。例えば:

// ------- usually the same for all
private static final String AUTHORITY = "de.vogella.android.todos.contentprovider";

// ------- define some Uris
private static final String PATH_TODOS = "todos";
private static final String PATH_REMINDERS = "reminders";

public static final Uri CONTENT_URI_TODOS = Uri.parse("content://" + AUTHORITY
    + "/" + PATH_TODOS);
public static final Uri CONTENT_URI_REMINDERS = Uri.parse("content://" + AUTHORITY
        + "/" + PATH_REMINDERS);

// ------- maybe also define CONTENT_TYPE for each

// ------- setup UriMatcher
private static final int TODOS = 10;
private static final int TODO_ID = 20;
private static final int REMINDERS = 30;
private static final int REMINDERS_ID = 40;
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
  sURIMatcher.addURI(AUTHORITY, PATH_TODOS, TODOS);
  sURIMatcher.addURI(AUTHORITY, PATH_TODOS + "/#", TODO_ID);
  sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS, REMINDERS);
  sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS + "/#", REMINDERS_ID);
}

//@Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {

    // Using SQLiteQueryBuilder instead of query() method
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

    int uriType = sURIMatcher.match(uri);
    switch (uriType) {

        case TODO_ID:
            // Adding the ID to the original query
            queryBuilder.appendWhere(TodoTable.COLUMN_ID + "="
                    + uri.getLastPathSegment());
            //$FALL-THROUGH$
        case TODOS:
            queryBuilder.setTables(TodoTable.TABLE_TODO);
            break;

        case REMINDERS_ID:
            // Adding the ID to the original query
            queryBuilder.appendWhere(ReminderTable.COLUMN_ID + "="
                    + uri.getLastPathSegment());
            //$FALL-THROUGH$
        case REMINDERS:
            queryBuilder.setTables(ReminderTable.TABLE_REMINDER);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
  }

queryBuilder.setTables(String inTables)にテーブル名を追加する必要がありますか?

はい、Uri異なるテーブルから異なるが読み取られた場合は、URIの一致に基づいてテーブルを設定します。

CONTENT_TYPEとCONTENT_ITEM_TYPEはどうですか?テーブルごとに1つある必要がありますか?

実際のコンテンツタイプによって異なります。それらが異なり、タイプyesが必要な場合。しかし、それらを持っている必要はまったくありません。その例はそれらを定義していますが、それらを使用していません。タイプを返す必要があります。ドキュメントgetTypeを参照してください。

TODO変数とTODO_ID変数、およびクエリメソッドのスイッチについてはどうでしょうか。

これらは、ここでUriMatcherうまく説明されているに対して定義された定数です。これは基本的に文字列照合を単純化したものです。ビッグは100の異なるURIを持つことができ、最後まで書く必要がある場合、適切なテーブルを選択するのは面倒です。ContentProviderqueryif (uri.getPath().equals("todos") { /* code */ } else if (uri..

于 2012-11-26T21:16:48.450 に答える
1

UriMatcherを使用すると、コンテンツプロバイダーに複数のテーブルを実装できます。

于 2013-02-08T19:10:18.413 に答える
0

コンテンツタイプとコンテンツアイテムは次のようになり、テーブルごとに個別のクラスにラップできます。

public static final String GENERAL_CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myfirstapp.db.member" ; public static final String SPECIFIC_CONTENT_TYPE = "vnd.android.cursor.item/vnd.myfirstapp.db.member" ;

`vnd.android.cursor.dir / vnd.yourownanything.anything.tablename '

これは、一般的なコンテンツタイプ `vnd.android.cursor.item / vnd.anthingasabove.table'を定義します。これは、特定のコンテンツタイプも定義し、これらの文字列(単語)vnd.android.cursor.dirおよび.itemはすべてのアプリに対して一定である必要があります。そのように/vndの後。そのようでなければなりません

また、contentproviderを拡張するクラスでは、UriMatcherの同じインスタンスを使用してテーブルをマップします。

于 2014-02-21T17:58:01.910 に答える