11

私は、SQLite データベースでクエリを実行ContentProviderできるAndroid を持っています。LEFT OUTER JOIN

データベースに 、UsersArticlesおよびの 3 つのテーブルがあるとしCommentsます。は次のContentProviderようなものです。

public class SampleContentProvider extends ContentProvider {
    private static final UriMatcher sUriMatcher;
    public static final String AUTHORITY = "com.sample.contentprovider";
    private static final int USERS_TABLE = 1;
    private static final int USERS_TABLE_ID = 2;
    private static final int ARTICLES_TABLE = 3;
    private static final int ARTICLES_TABLE_ID = 4;
    private static final int COMMENTS_TABLE = 5;
    private static final int COMMENTS_TABLE_ID = 6;
    private static final int ARTICLES_USERS_JOIN_TABLE = 7;
    private static final int COMMENTS_USERS_JOIN_TABLE = 8;

    // [...] other ContentProvider methods

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        String table = getTableName(uri);

        // SQLiteWrapper is a wrapper class to manage a SQLiteHelper
        Cursor c = SQLiteWrapper.get(getContext()).getHelper().getReadableDatabase()
                .query(table, projection, selection, selectionArgs, null, null, sortOrder);

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

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        String table = getTableName(uri);

        // SQLiteWrapper is a wrapper class to manage a SQLiteHelper
        long id = SQLiteWrapper.get(getContext()).getHelper().getWritableDatabase()
                .insert(table, null, values);

        Uri itemUri = ContentUris.withAppendedId(uri, id);
        getContext().getContentResolver().notifyChange(itemUri, null);

        return itemUri;
    }

    private String getTableName(Uri uri) {
        switch (sUriMatcher.match(uri)) {
        case USERS_TABLE:
        case USERS_TABLE_ID:
            return "Users";

        case ARTICLES_TABLE:
        case ARTICLES_TABLE_ID:
            return "Articles";

        case COMMENTS_TABLE:
        case COMMENTS_TABLE_ID:
            return "Comments";

        case ARTICLES_USERS_JOIN_TABLE:
            return "Articles a LEFT OUTER JOIN Users u ON (u._id = a.user_id)";

        case COMMENTS_USERS_JOIN_TABLE:
            return "Comments c LEFT OUTER JOIN Users u ON (u._id = c.user_id)";

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

    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(AUTHORITY, "users", USERS_TABLE);
        sUriMatcher.addURI(AUTHORITY, "articles", ARTICLES_TABLE);
        sUriMatcher.addURI(AUTHORITY, "comments", COMMENTS_TABLE);
        sUriMatcher.addURI(AUTHORITY, "users" + "/#", USERS_TABLE_ID);
        sUriMatcher.addURI(AUTHORITY, "articles" + "/#", ARTICLES_TABLE_ID);
        sUriMatcher.addURI(AUTHORITY, "comments" + "/#", COMMENTS_TABLE_ID);
        sUriMatcher.addURI(AUTHORITY, "???", ARTICLES_USERS_JOIN_TABLE); // what uri here?
        sUriMatcher.addURI(AUTHORITY, "???", COMMENTS_USERS_JOIN_TABLE); // what uri here?
    }
}

テーブルCursorAdapterに行を挿入 (または更新) するたびに、結合されたクエリと結合されていないクエリをリッスンしているすべての s に通知するための最適な URI スキームは何ですか?Users

つまり、テーブルの 1 つで新しい行を追加または更新する場合、1 つの通知を送信して任意のクエリ ( 、、 ) をリッスンしgetContext().getContentResolver().notifyChange(itemUri, null)ているすべてのがコンテンツを更新するための通知を受け取るようにします。CursorAdapterUSERS_TABLEARTICLES_USERS_JOIN_TABLECOMMENTS_USERS_JOIN_TABLE

これが不可能な場合、すべてのオブザーバーに通知する別の方法はありますか?

4

2 に答える 2

5

次のクエリを実行する特別な Uri を使用できます。

    sUriMatcher.addURI(AUTHORITY, "articlesusers", ARTICLES_USERS_JOIN_TABLE);
    sUriMatcher.addURI(AUTHORITY, "commentsusers", COMMENTS_USERS_JOIN_TABLE);

しかし、単一の通知を送信する方法が思いつきません。変更中のテーブルを参照する Uri ごとに通知を送信するのが最善の選択のようです。したがって、挿入/更新/削除メソッドは、影響を受けるテーブルに応じて、notifyChange を複数回呼び出します。「users」への変更の場合、「users」テーブルに依存しているため、users、articlesusers、commentsusers の 3 つの通知になります。

于 2012-07-26T03:18:22.727 に答える
1

prodaeaが回答したように、通知 Uri に使用できる別の代替手段を次に示します。これは完全な解決策ではありませんが、通知に使用する Uri は 1 つだけです。

解決策は、テーブル名のないメイン URI (例: content://com.example.app.provider/) をARTICLES_USERS_JOIN_TABLEおよびのクエリ メソッドで通知 URI として使用することですCOMMENTS_USERS_JOIN_TABLE。そのため、テーブルに変更があるたびに、関連するカーソルに通知されます。ただし、1 つの制限があります。つまりARTICLES_USERS_JOIN_TABLE、テーブルに変更があった場合でもカーソルが通知されArticlesます。

テーブル、Users' andArticles については、通知用に特定の Uris を使用できます。

于 2015-09-28T12:18:17.923 に答える