2013-06-12 12 views
6

私はコンテンツプロバイダ、コンテンツリゾルバ、およびカーソルローダを持っています。ローダーは、他のデータを収集するためにカーソルの結果を使用する必要があるため、間接的にリストビューを作成するために使用されます(単純なカーソルアダプタではなく、配列アダプタです)。基本データが変更されたときにカーソルローダーがリフレッシュされない

基になるデータを変更すると、コールバックが呼び出されないため、リストビューは再入力されません(onLoadFinished(Loader<Cursor>, Cursor))。

私がこれを書いている間に示唆されているように、この問題について多くの質問があります。 例えば CursorLoader not updating after data change

そして、すべての質問には二つのことを指摘:あなたのコンテンツプロバイダのquery()メソッドでは

  • は、あなたがa'la通知に関するカーソルを伝える必要があり

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

  • コンテンツプロバイダの挿入/更新/削除メソッドでは、n URIにotify:

getContext().getContentResolver().notifyChange(uri, null);

私はそれらの事をやっています。

私は戻ってくるカーソルも閉じていません。

私のコンテンツプロバイダは独立したアプリであることに注意してください(コンテンツプロバイダーアプリと考えています - ランチャーのメインアクティビティはありません)。 com.example.provider APK、com.example.appはcontent://com.example.provider/table URIなどを使用して(コンテンツリゾルバで)呼び出しています。コンテンツリゾルバ(dbhelper)は、ライブラリプロジェクト(この方法では、複数のプロジェクトがリンク経由でdbhelperを使用でき、すべてのコンテンツプロバイダは単一のAPK経由でインストールされます)

ローダーマネージャでデバッグを有効にしましたが、データが変更された後(つまり、ローダーが再起動され、以前に非アクティブとマークされている)、強制的にリフレッシュを強制的に実行する場所を知ることができます。

私のローダーがリフレッシュされていない理由はありますか?

- EDIT -

ローダの作成:

介しからgetfoo()はカーソルローダーを返し
Log.d(TAG, "onCreateLoader ID: " + loaderID); 
// typically a switch on the loader ID, and then 
return dbHelper.getfoo() 

:ローダー完了カーソルとを移入をとる

return new CursorLoader(context, FOO_URI, foo_Fields, foo_query, foo_argArray, foo_sort);

テーブル(といくつかの処理を行う) - 何もそこに空想。

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    Log.d(TAG, "onLoadFinished id: " + loader.getId()); 
    // switch on loader ID .. 
    FillTable(cursor, (FooAdapter) foo_info.listview.getAdapter(); 

ローダーリセットはテーブルを消去します。

public void onLoaderReset(Loader<Cursor> loader) { 
    Log.d(TAG, "onLoaderReset id: " + loader.getId()); 
    // normally a switch on loader ID 
    ((FooAdapter)foo_info.listview.getAdapter()).clear(); 

コンテンツプロバイダはない:

公共カーソルクエリ(URIのURI、文字列[]投影、ストリング選択、文字列[] selectionArgs、文字列はsortOrder){ カーソルカーソルを、 SQLiteQueryBuilder qb =新しいSQLiteQueryBuilder();その後

SQLiteDatabase db = dbHelper.getReadableDatabase(); 

    switch (sUriMatcher.match(uri)) { 
    case FOO: 
     qb.setTables(FOO); 
     qb.setProjectionMap(FooProjectionMap); 
     break; 
    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); 

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

}

/更新を挿入似ています。

public Uri insert(Uri uri, ContentValues initialValues) { 
    ContentValues values; 
    if (initialValues != null) { 
     values = new ContentValues(initialValues); 
    } else { 
     values = new ContentValues(); 
    } 

    String tableName; 
    Uri contentUri; 

    switch (sUriMatcher.match(uri)) { 
    case FOO: 
     tableName = FOOTABLE; 
     contentUri = FOO_URI; 
     break; 

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

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    long rowId = db.insert(tableName, null, values); 
    if (rowId > 0) { 
     Uri objUri = ContentUris.withAppendedId(contentUri, rowId); 
     getContext().getContentResolver().notifyChange(objUri, null); 
     return objUri; 
    } 

    throw new SQLException("Failed to insert row into " + uri); 
} 
+0

カーソルローダーに関連するコードの一部を投稿すると役立ちます。主にonCreateLoader、onLoaderReset、onLoadFinishedメソッド。 リフレッシュ時にContentProviderがnotifyChangeコールに到達すると仮定しています。 – AfzalivE

+0

申し訳ありませんが、暴風雨や停電などはしばらくの間私を遠ざけました。 –

答えて

2

私はあなたがあなたのonLoadFinishedとonLoaderResetにswapCursorまたはchangeCursorを呼び出していないことがわかります。新しいカーソルにロードされたデータにアクセスするには、アダプターを使用する必要があります。 onLoadFinishedで

、のようなものを呼び出す:mAdapterはあなたのListViewのアダプタです

mAdapter.swapCursor(null) 

onLoaderResetで
mAdapter.swapCursor(cursor) 

を、古いカーソルへの参照を削除するには、これを呼び出します。

詳細情報:だからhttp://developer.android.com/guide/components/loaders.html#onLoadFinished

+0

私はコード内の最初の例を選択しているかもしれません。一つは配列アダプターです。なぜなら、カーソルにない情報や、カーソルが来るDB(つまり、別のデータベースにあります。私はクエリでJOINを使用することはできません)。返されるデータに '** swapCursor()'を行う他のsimplecursoradapter(または単純なカーソルから派生したもの)がいくつかあります(自動リフレッシュもしません)。 –

+0

SimpleCursorAdapterを使用していて、追加情報を検索していますか?私には、アダプタークラスの追加検索を行うカスタムアダプターを使用する方が良いかもしれないと思う。私は 'swapCursor()'と呼ばれる他のものを見なければならないが、他の問題があるかもしれないのでリフレッシュされない。 – AfzalivE

2

、これを検索し、この問題を持っている人のために:

あなたは上のカーソルを通知し、特定のURIを使用すると、上のカーソルを登録し、URIことを確認してください同じ。

私のケースでは、基になるテーブルを変更した他のコードで使用されていたクエリとは異なるURIを使用していました。通知作業を行う簡単な修正はありませんでした。そのため、OnResume()のローダーをソリューションとして再設定しました。

1

これはこの特定の問題に対する直接の回答ではありませんが、同様の状況で他の人に役立つ可能性があります。私の場合、私は参加していましたが、投影とクエリで完全なtablename.columnnameを使用しましたが。それはとにかく間違ったID値を使用して終わった。 ContentProviderまたはSQLの構文を確認してください。

関連する問題