Android ContentProvider URI方案,用于通知CursorAdapters监听OUTER JOIN查询

Lor*_*ori 11 sqlite android join cursor android-contentprovider

我有一个ContentProvider允许LEFT OUTER JOIN在SQLite数据库上进行查询的Android .

让我们假设在数据库中我有3个表Users,Articles和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?
    }
}
Run Code Online (Sandbox Code Playgroud)

CursorAdapter每次在Users表中插入(或更新)行时,通知所有侦听已加入和未加入的查询的最佳URI方案是什么?

换句话说,如果我添加或更新表中的一个新行,我想送一个单一的通知,getContext().getContentResolver().notifyChange(itemUri, null)让所有的CursorAdapter在听我说话的任何查询(USERS_TABLE,ARTICLES_USERS_JOIN_TABLE,COMMENTS_USERS_JOIN_TABLE)收到通知,以更新他们的内容.

如果这是不可能的,是否有另一种方式通知所有观察者?

sat*_*ine 5

您可以使用特殊的Uri来查询:

    sUriMatcher.addURI(AUTHORITY, "articlesusers", ARTICLES_USERS_JOIN_TABLE);
    sUriMatcher.addURI(AUTHORITY, "commentsusers", COMMENTS_USERS_JOIN_TABLE);
Run Code Online (Sandbox Code Playgroud)

但我想不出发送单一通知的方法.看来你最好的选择是为每个引用被修改表的Uri发送通知.因此,您的insert/update/delete方法会多次调用notifyChange,具体取决于受影响的表.对于"用户"的更改,它将是3个通知 - 用户,文章用户和评论用户 - 因为它们都依赖于"用户"表.