获取SQLiteCursorLoader以观察数据更改

时间:2012-01-30 07:44:38

标签: android android-cursorloader commonsware-cwac

我正在尝试使用Commonsware中使用Loader的适配器实现DataListFragment。此Loader直接使用SQLiteDatabase,不需要使用ContentProviders。

关于Loaders的android参考说明: “当Loaders处于活动状态时,他们应该监控数据来源,并在内容发生变化时提供新的结果。”

在我的SQLiteCursor实现(下面)中,这不会发生。 OnLoadFinished()被调用一次,就是这样。据推测,可以在基础数据库发生更改的地方插入Loader.onContentChanged()调用,但一般来说数据库代码类不了解加载器,因此我不确定实现此目的的最佳方法。

有没有人对使用Loader“数据感知”有任何建议,或者我应该将数据库内容包装为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);
}

1 个答案:

答案 0 :(得分:20)

Loader文档存在缺陷。

100%内置于Android内的Loader实现“监控其数据来源,并在内容发生变化时提供新结果”。由于目前Android内部只有一个Loader实现,因此他们的文档准确无误。

然而,引用我应该在一两个小时内发布的一本书的更新:

  

框架中没有任何内容需要这样做   行为。此外,在某些情况下,显然这是一个坏主意   这个 - 想象一个Loader从Internet上加载数据,需要   不断轮询某个服务器以寻找变化。

如果您通过它路由所有数据库修改,我计划扩充SQLiteCursorLoader以至少更多地了解数据库更改。这也有局限性,因为你不在活动之间共享Loader个对象(更不用说从服务中访问它们了)。

CursorLoader工作的唯一原因是因为它使用ContentProvider - 一个可以因此了解所有操作的单例。

目前,代码中负责插入,更新和删除的任何部分都需要点击肩膀上的SQLiteCursorLoader并更新,或通知活动更改(例如,从Service广播,以便活动可以点击肩膀上的SQLiteCursorLoader