获取SQLiteCursorLoader观察数据的变化 [英] Getting SQLiteCursorLoader to observe data changes

查看:118
本文介绍了获取SQLiteCursorLoader观察数据的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现与使用从Commonsware一个装载机的适配器DataListFragment。该装载机采用了SQLiteDatabase直接,并不需要使用ContentProviders的。

有关装载机Android的参考状态: 虽然装载机是活动的,他们应该监控其数据源,并提供新的成果的时候,内容的变化。

在我SQLiteCursor执行(下),不会发生这种情况。 OnLoadFinished()被调用一次,仅此而已。 presumably,我们可以插入 Loader.onContentChanged()调用其中底层数据库得到改变,但在一般的数据库code类不知道装载机,所以我不知道要实现此最好的方式。

有没有人有使装载机数据感知的建议,或者我应该换了数据库的东西作为一个的ContentProvider和使用CursorLoader呢?

 进口com.commonsware.cwac.loaderex.SQLiteCursorLoader;

公共类DataListFragment扩展ListFragment实现LoaderManager.LoaderCallbacks<光标> {

保护DataListAdapter mAdapter; //这是适配器被用于显示该列表的数据。
公共SQLiteDatabase mSqlDb;
私有静态最终诠释LOADER_ID = 1;

@覆盖
公共无效onActivityCreated(包savedInstanceState){
    super.onActivityCreated(savedInstanceState);
    INT rowlayoutID = getArguments()调用getInt(rowLayoutID)。
    //创建一个空的适配器,我们将用它来显示加载的数据。
    //我们通过0到标志,因为加载器将监视数据的变化
    mAdapter =新DataListAdapter(getActivity(),rowlayoutID,空,0);
    setListAdapter(mAdapter);
    // prepare装载机。无论是与现有的一个重新连接,
    //或者开始一个新的。
    LoaderManager LM = getLoaderManager();
    // OnLoadFinished被调用后,这一点,但从来没有一次。
    lm.initLoader(LOADER_ID,空,这一点);
}
公共装载机<光标> onCreateLoader(INT ID,捆绑参数){
    字符串SQL =SELECT * FROM+ TABLE_NAME +;
    的String [] PARAMS = NULL;
    SQLiteCursorLoader CursorLoader =新SQLiteCursorLoader(getActivity(),mSqlDb,SQL,则params);
    返回CursorLoader;
}
公共无效onLoadFinished(装载机<光标>装载机,光标数据){
    //更换为新的光标。(该框架将收旧光标一旦我们返回的照顾。)
    mAdapter.swapCursor(数据);
    //现在应该显示的列表。
    如果(isResumed()){setListShown(真);}
    其他{setListShownNoAnimation(真正的); }
}
公共无效onLoaderReset(装载机<光标>装载机){
    //这就是所谓的当提供给onLoadFinished一个光标()
    //以上即将被关闭。我们需要确保我们没有
    //不再使用它。
    mAdapter.swapCursor(空);
}
 

解决方案

装载机文件是有缺陷的。

内置到Android的自身装载机实现100%监控其数据源,并提供新的成果的时候,内容的变化。由于只有一个装载机实施建设成为Android的自身截至目前,他们的资料是准确的,只要那个去。

不过,引用我的书更新,它应该被释放在一个小时或两个:

  

有没有在框架需要此   行为。此外,也有一些情况下,显然是一个糟糕的主意,这样做   这 - 想象一个装载机装载数据在互联网上传播,需要以   不断查询一些服务器,以寻找变化。

我不打算充实 SQLiteCursorLoader 来至少多一点了解数据库的更改,如果路由经过的所有数据库修改。这也将有一定的局限性,因为你不活动之间共享装载机对象(更不用说具有服务访问它们)。

唯一 CursorLoader 工作的原因,因为它确实是因为它使用了的ContentProvider - 一个单身的,因此可以要知道所有的操作。

目前,无论你的code部分负责插入,更新和删除要么需要点击 SQLiteCursorLoader 的肩膀,有它更新或更改通知的活动(例如,从广播服务),这样的活动可以点击 SQLiteCursorLoader 的肩膀。

I'm trying to implement a DataListFragment with an adapter that uses a Loader from Commonsware. This Loader uses a SQLiteDatabase directly and doesn't require the use of ContentProviders.

The android reference states about Loaders: "While Loaders are active they should monitor the source of their data and deliver new results when the contents change."

Under my SQLiteCursor implementation (below), this does not happen. OnLoadFinished() gets called once and that's it. Presumably, one could insert Loader.onContentChanged() calls where the underlying database gets changed, but in general the database code class does not know about loaders, so I'm not sure about the best way to go about implementing this.

Does anyone have any advice on making the Loader "data aware", or should I wrap the database stuff in as a ContentProvider and use CursorLoader instead?

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);
}

解决方案

The Loader documentation is flawed.

100% of Loader implementations built into Android itself "monitor the source of their data and deliver new results when the contents change". Since there is only one Loader implementation built into Android itself as of now, their documentation is accurate as far as that goes.

However, quoting a book update of mine that should be released in an hour or two:

There is nothing in the framework that requires this behavior. Moreover, there are some cases where is clearly a bad idea to do this – imagine a Loader loading data off of the Internet, needing to constantly poll some server to look for changes.

I do plan on augmenting SQLiteCursorLoader to be at least a bit more aware of database changes, if you route all database modifications through it. That too will have limitations, because you don't share Loader objects between activities (let alone have access to them from services).

The only reason CursorLoader works as it does is because it uses a ContentProvider -- a singleton that can therefore be aware of all operations.

At the moment, whatever portion of your code is responsible for inserts, updates, and deletes will either need to tap the SQLiteCursorLoader on the shoulder and have it update, or notify the activity of the change (e.g., broadcast from a Service) so the activity can tap the SQLiteCursorLoader on the shoulder.

这篇关于获取SQLiteCursorLoader观察数据的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆