从ContentProvider中未正确调用onLoadFinished

时间:2016-11-09 23:41:53

标签: android sqlite broadcastreceiver android-contentprovider simplecursoradapter

我在MainActivity中有两个不同的SimpleCursorAdapters和链接的ListView。用以下内容初始化它们:

getLoaderManager().initLoader(0, null, this);
getLoaderManager().initLoader(2, null, this);

初始化后,将创建两个加载器,并在ContentProvider上运行查询并正确返回数据。

LoaderManager实施:

@Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        CursorLoader loader = null;

        switch (id) {
            case 0:
                loader = new CursorLoader(this,
                        DataProvider.CONTENT_URI_PROFILE_Match,
                        new String[]{DataProvider.COL_ID, DataProvider.COL_MATCH_NAME, DataProvider.COL_COUNT, DataProvider.COL_MATCH_PROFILE_IMAGE, DataProvider.COL_MATCH_BIRTH_DATE},
                        null,
                        null,
                        DataProvider.COL_ID + " DESC");
                break;
            case 2:
                loader = new CursorLoader(this,
                        DataProvider.CONTENT_URI_PROFILE_Trash,
                        new String[]{DataProvider.COL_ID, DataProvider.COL_MATCH_NAME, DataProvider.COL_EXPIRATION_STATUS, DataProvider.COL_MATCH_PROFILE_IMAGE, DataProvider.COL_MATCH_BIRTH_DATE},
                        null,
                        null,
                        DataProvider.COL_ID + " DESC");
                break;
        }
        return loader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        switch (loader.getId()) {
            case 0:
                adapterMatch.swapCursor(data);
                break;
            case 2:
                adapterTrash.swapCursor(data);
                break;
        }
    }

该应用程序的工作原理如下。当从BroadCastReceiver上的服务器接收消息时,下面的部分代码将在Receiver类上运行并通过ContentProvider在db中插入一行

ContentValues values = new ContentValues(5);
                    values.put(DataProvider.COL_MATCH_ID, matchedUser);
                    values.put(DataProvider.COL_EXPIRATION_STATUS, expirationStatus);
                    values.put(DataProvider.COL_MATCH_NAME, matchName);
                    values.put(DataProvider.COL_MATCH_BIRTH_DATE, matchBirthDate);
                    values.put(DataProvider.COL_MATCH_PROFILE_IMAGE, matchProfileImage);
                    context.getContentResolver().insert(DataProvider.CONTENT_URI_PROFILE_Match, values);

我的问题是在从服务器接收到的新值插入SQLite数据库之后,游标数据不会传递给MainActivity,因此在下次创建Activity之前不会更新UI。

以下是我的ContentProvider中突出显示的代码:

public static final Uri CONTENT_URI_MESSAGES = Uri.parse("content://com.example.vcc4.mashroom.provider/messages");
    public static final Uri CONTENT_URI_PROFILE = Uri.parse("content://com.example.vcc4.mashroom.provider/profile");
    public static final Uri CONTENT_URI_PROFILE_Match = Uri.parse("content://com.example.vcc4.mashroom.provider/match");
    public static final Uri CONTENT_URI_PROFILE_Trash = Uri.parse("content://com.example.vcc4.mashroom.provider/trash");

private static final UriMatcher uriMatcher;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.vcc4.mashroom.provider", "messages", MESSAGES_ALLROWS);
        uriMatcher.addURI("com.example.vcc4.mashroom.provider", "messages/#", MESSAGES_SINGLE_ROW);
        uriMatcher.addURI("com.example.vcc4.mashroom.provider", "profile", PROFILE_ALLROWS);
        uriMatcher.addURI("com.example.vcc4.mashroom.provider", "profile/#", PROFILE_SINGLE_ROW);
        uriMatcher.addURI("com.example.vcc4.mashroom.provider", "match", PROFILE_AllROWS_MATCH);
        uriMatcher.addURI("com.example.vcc4.mashroom.provider", "match/#", PROFILE_SINGLE_ROWS_MATCH);
        uriMatcher.addURI("com.example.vcc4.mashroom.provider", "trash", PROFILE_ALLROWS_TRASH);
    }

@Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        switch(uriMatcher.match(uri)) {
        case MESSAGES_ALLROWS:
            qb.setTables(TABLE_MESSAGES);
            break;          

        case MESSAGES_SINGLE_ROW:
            qb.setTables(TABLE_MESSAGES);
            qb.appendWhere("_id = " + uri.getLastPathSegment());
            break;

        case PROFILE_ALLROWS:
            qb.setTables(TABLE_PROFILE);
            break;          

        case PROFILE_SINGLE_ROW:
            qb.setTables(TABLE_PROFILE);
            qb.appendWhere("_id = " + uri.getLastPathSegment());
            break;

        case PROFILE_AllROWS_MATCH:
            qb.setTables(TABLE_PROFILE);
            qb.appendWhere(COL_EXPIRATION_STATUS + " = " + "'wait'" + " OR " + COL_EXPIRATION_STATUS + " = " + "'active'");
            break;

        case PROFILE_ALLROWS_TRASH:
            qb.setTables(TABLE_PROFILE);
            qb.appendWhere(COL_EXPIRATION_STATUS + " = " + "'expired'");
            break;

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

        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

@Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        long id;
        switch(uriMatcher.match(uri)) {
        case MESSAGES_ALLROWS:
            id = db.insertOrThrow(TABLE_MESSAGES, null, values);
            if (values.get(COL_TO) == null) {
                db.execSQL("update profile set count = count+1 where email = ?", new Object[]{values.get(COL_FROM)});
                getContext().getContentResolver().notifyChange(CONTENT_URI_PROFILE, null);
            }
            break;

        case PROFILE_ALLROWS:
            id = db.insertOrThrow(TABLE_PROFILE, null, values);
            break;

        case PROFILE_AllROWS_MATCH:
            id = db.insertOrThrow(TABLE_PROFILE, null, values);
            break;

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

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

        return insertUri;
    }

我搜索过很多SO问题和android资源,但找不到解决这个问题的任何线索。有什么解决方案吗?

下面的

编辑添加了设置SimpleCursorAdapters的代码:

adapterMatch = new SimpleCursorAdapter(this,
                R.layout.main_list_item,
                null,
                new String[]{DataProvider.COL_MATCH_PROFILE_IMAGE, DataProvider.COL_MATCH_NAME, DataProvider.COL_MATCH_BIRTH_DATE, DataProvider.COL_COUNT, DataProvider.COL_MATCH_ID},
                new int[]{R.id.avatar, R.id.text1, R.id.text2, R.id.text3},
                0);
adapterWatch = new SimpleCursorAdapter(this,
                    R.layout.main_list_item,
                    null,
                    new String[]{DataProvider.COL_MATCH_PROFILE_IMAGE, DataProvider.COL_MATCH_NAME, DataProvider.COL_MATCH_BIRTH_DATE, DataProvider.COL_MUTUAL_ACTION, DataProvider.COL_EXPIRATION_STATUS, DataProvider.COL_MATCH_ID},
                    new int[]{R.id.avatar, R.id.text1, R.id.text2, R.id.text3},
                    0);
adapterTrash = new SimpleCursorAdapter(this,
                    R.layout.main_list_item,
                    null,
                    new String[]{DataProvider.COL_MATCH_PROFILE_IMAGE, DataProvider.COL_MATCH_NAME, DataProvider.COL_MATCH_BIRTH_DATE, DataProvider.COL_EXPIRATION_STATUS},
                    new int[]{R.id.avatar, R.id.text1, R.id.text2, R.id.text3},
                    0);

1 个答案:

答案 0 :(得分:0)

可能没什么,但您是否介意在插入匹配项时调试并检查insertUri方法的insert方法的第4行ContentProvider变量的值?