4

Commonswareのローダ​​ーを使用するアダプターを使用してDataListFragmentを実装しようとしています。このローダーはSQLiteDatabaseを直接使用し、ContentProviderを使用する必要はありません。

androidリファレンスには、ローダーについて次のように記載されています。「ローダーがアクティブな間は、データのソースを監視し、コンテンツが変更されたときに新しい結果を提供する必要があります。」

私のSQLiteCursor実装(下記)では、これは起こりません。OnLoadFinished()一度呼び出されるとそれだけです。おそらく、Loader.onContentChanged()基になるデータベースが変更された場所に呼び出しを挿入できますが、一般にデータベースコードクラスはローダーについて認識していないため、これを実装するための最善の方法がわかりません。

ローダーを「データ対応」にするためのアドバイスはありますか、それともデータベースのものをContentProviderとしてラップし、代わりにCursorLoaderを使用する必要がありますか?

import com.commonsware.cwac.loaderex.SQLiteCursorLoader;

public class DataListFragment extends ListFragment implements    LoaderManager.LoaderCallbacks<Cursor>{

protected DataListAdapter  mAdapter;     // This is the Adapter being used to display the list's data.
public SQLiteDatabase      mSqlDb;
private static final int   LOADER_ID = 1;

@Override 
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    int rowlayoutID = getArguments().getInt("rowLayoutID");
    // Create an empty adapter we will use to display the loaded data.
    // We pass 0 to flags, since the Loader will watch for data changes
    mAdapter = new DataListAdapter(getActivity(),rowlayoutID, null , 0);
    setListAdapter(mAdapter);
    // Prepare the loader.  Either re-connect with an existing one,
    // or start a new one.
    LoaderManager lm = getLoaderManager();
    // OnLoadFinished gets called after this, but never again.
    lm.initLoader(LOADER_ID, null, this);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String sql="SELECT * FROM "+TABLE_NAME+";";
    String[] params = null;
    SQLiteCursorLoader CursorLoader = new SQLiteCursorLoader(getActivity(), mSqlDb, sql, params);
    return CursorLoader;
}
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.)
    mAdapter.swapCursor(data);
    // The list should now be shown.
    if (isResumed()) { setListShown(true);} 
    else { setListShownNoAnimation(true); }
}
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.
    mAdapter.swapCursor(null);
}
4

1 に答える 1

20

Loaderドキュメントに欠陥があります。

LoaderAndroid自体に組み込まれている実装の100%は、 「データのソースを監視し、コンテンツが変更されたときに新しい結果を提供します」。現在、Android自体に組み込まれている実装は1つしかないためLoader、そのドキュメントはそれに関する限り正確です。

ただし、1〜2時間以内にリリースされるはずの私の本の更新を引用します。

この動作を必要とするフレームワークには何もありません。さらに、これを行うのは明らかに悪い考えである場合があります。ローダーがインターネットからデータをロードし、変更を探すためにサーバーを常にポーリングする必要があると想像してください。

SQLiteCursorLoaderすべてのデータベース変更をデータベースにルーティングする場合は、データベースの変更を少なくとももう少し意識するように拡張する予定です。Loaderアクティビティ間でオブジェクトを共有しないため(サービスからオブジェクトにアクセスできることは言うまでもなく)、これにも制限があります。

唯一の理由は、それがすべての操作を認識できるシングルトンをCursorLoader使用しているためです。ContentProvider

現時点では、コードの挿入、更新、削除を担当する部分はSQLiteCursorLoader、肩をタップして更新するか、変更のアクティビティに通知する(たとえば、からブロードキャストするService)必要があります。SQLiteCursorLoader肩をタップします。

于 2012-01-30T12:22:53.437 に答える