2011-12-29 9 views
7

私は単純なcontentProviderを持っています。これは、ListViewを持つレイアウトと、コンテンツプロバイダとCursorLoaderにアイテムを追加するためのボタンです。 http://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished(android.content.Loader、D)参照状態なぜcursorLoaderはソースデータの変更を通知しませんでしたか?

Loaderは、データへの変更を監視し、ここに新しいコールをご に報告すること。自分でデータを監視すべきではありません。例えば 、データがカーソルであり、あなたが CursorAdapterに入れた場合、つまり( FLAG_AUTO_REQUERYまたはFLAG_REGISTER_CONTENT_OBSERVERのいずれかに渡さずにCursorAdapter(android.content.Context、 android.database.Cursor、INT)コンストラクタを使用しますflags引数に0 を使用してください)。これにより、CursorAdapterが 独自のCursorの観測を実行するのを防ぎます。これは、 の変更が発生したときに、新しいCursorで別の呼び出しが発生するためです。

しかし、onLoadFinishedメソッドのLog.info行は実行されず、listViewは更新されませんでした。ここに私の(シンプルな)コードがあります:

public class HomeActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>{ 
static final String TAG = "HomeActivity"; 
SimpleCursorAdapter adapter; 
ListView listAnnunciVicini; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.home); 

    listAnnunciVicini = (ListView) findViewById(R.id.lista_annunci_vicini); 

    adapter = new SimpleCursorAdapter(this, R.layout.list_item, null, 
      new String[] { 
        ContentDescriptor.Annunci.Cols.ID, 
        ContentDescriptor.Annunci.Cols.TITOLO, 
        ContentDescriptor.Annunci.Cols.DESCRIZIONE 
      }, new int[] { 
        R.id.list_annunci_item_id_annuncio, 
        R.id.list_annunci_item_titolo_annuncio, 
        R.id.list_annunci_item_descrizione_annuncio 
      }, 0); 
    listAnnunciVicini.setAdapter(adapter); 

    // Prepare the loader. Either re-connect with an existing one, 
    // or start a new one. 
    getSupportLoaderManager().initLoader(0, null, this).forceLoad(); 
} 

public void addRandomItem(View sender) { 
    ContentValues dataToAdd = new ContentValues(); 
    dataToAdd.put(ContentDescriptor.Annunci.Cols.TITOLO, "Titolo"); 
    dataToAdd.put(ContentDescriptor.Annunci.Cols.DESCRIZIONE, "Lorem ipsum dolor sit amet."); 
    this.getContentResolver().insert(ContentDescriptor.Annunci.CONTENT_URI, dataToAdd); 
} 

@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    // creating a Cursor for the data being displayed. 
    String[] proiezione = new String[] {ContentDescriptor.Annunci.Cols.ID, ContentDescriptor.Annunci.Cols.TITOLO, ContentDescriptor.Annunci.Cols.DESCRIZIONE }; 

    CursorLoader cl = new CursorLoader(this, ContentDescriptor.Annunci.CONTENT_URI, proiezione, null, null, null); 
    return cl; 
} 

public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    // Swap the new cursor in. (The framework will take care of closing the 
    // old cursor once we return.) 
    adapter.swapCursor(data); 
    Log.i(TAG, "I dati sono stati ricaricati"); 
} 

public void onLoaderReset(Loader<Cursor> loader) { 
    // This is called when the last Cursor provided to onLoadFinished() 
    // above is about to be closed. We need to make sure we are no 
    // longer using it. 
    adapter.swapCursor(null); 
} 
} 

何か提案がありますか?

答えて

20

AFAIK、あなた自身でContentProviderに通知を実装する必要があります。このため、ContentProviderinsertupdatedelete方法にgetContext().getContentResolver().notifyChange(uri, null);のようなものを追加し、official documentationで説明したようにqueryであなたのCursor.setNotificationUri(getContext().getContentResolver(), uri)を呼び出します。 Hereあなたは全体の画像を見つけることができます。

注:あなたが変更に関する 通知を得るためにカーソル(cursor.close())を閉じるべきではありません。

+0

古いmanagedQueryメソッドが廃止されたため、Android 3.X +の新しいローダーAPIを使用しています。私はContentProviderのnotifyChangeメソッドも持っています。 – ilcaduceo

+0

明確にするために、私はCursorLoadersについても話していました。 – ernazm

+4

私はいつも私のクエリでsetNotificationUriを忘れて、なぜカーソルローダーが新鮮でないのか不思議に思っています。 – Tarun

関連する問題