是否有必要同时实现LoaderCallbacks和OnLoadCompleteListener获得在ContentProvider的变化的通知? [英] Is it necessary to implement both LoaderCallbacks and OnLoadCompleteListener to get notifications of changes in a ContentProvider?

查看:247
本文介绍了是否有必要同时实现LoaderCallbacks和OnLoadCompleteListener获得在ContentProvider的变化的通知?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这是使用装载机 s到获得在这也正由 IntentService 。我收到的数据从装载机通过 LoaderCallbacks 执行,这是工作的罚款。

我也使用 ContentResolver的#有NotifyChange(URI,ContentObserver)触发重新加载。然而,当我把这个只适用光标#setNotificationUri(URI)事先

我能找到没有提及任何文档中的后一种方法,它似乎在事实上,这可能会导致死机:又见

<一个href=\"http://stackoverflow.com/questions/14956608/illegalstateexception-attempt-to-re-open-an-already-closed-object-in-simplecur\">IllegalStateException &QUOT;试图重新打开一个已关闭的对象&QUOT;在SimpleCursorAdapter从ContentProvider的

然而,如果没有对光标此调用 LoaderCallbacks#onLoadFinished(装载机&LT;游标&gt;中光标)是只有初始加载之后,并通知后未命中。难道我的需要实施 OnLoadCompleteListener 做的,好了,完全一样的东西?

的ContentProvider 查询方法:

 类MyContentProvider扩展ContentProvider的{
// ...    @覆盖
    公共光标查询(URI URI,字符串[]投影,字符串的选择,
            的String [] selectionArgs两个,字符串中将sortOrder){
        SQLiteDatabase分贝= mOpenHelper.getReadableDatabase();
        游标查询= db.query(getTableName时(URI),投影,选择,selectionArgs两个,NULL,NULL,中将sortOrder);
        query.setNotificationUri(的getContext()getContentResolver(),URI);
        返回查询;
    }// ...
}

典型 LoaderCallbacks

  LoaderCallbacks&LT;&光标GT; mCallbacks =新LoaderCallbacks&LT;&光标GT;(){    @覆盖
    公共无效onLoaderReset(装载机&LT;&光标GT;装载机){
        mArticleAdapter.swapCursor(NULL);
    }    @覆盖
    公共无效onLoadFinished(装载机&LT;&光标GT;装载机,光标光标){
        如果(cursor.isClosed()){
            Log.d(TAG,游标返回CLOSED);
            活动活动= getActivity();
            如果(活动!= NULL){
                。activity.getLoaderManager()restartLoader(mFragmentId,空,mCallbacks);
            }
            返回;
        }
        mArticleAdapter.swapCursor(光标);
    }    @覆盖
    公共装载机&LT;&光标GT; onCreateLoader(INT ID,捆绑参数){
        triggerArticleFeed();
        CursorLoader cursorLoader = NULL;        如果(ID == mFragmentId){
            cursorLoader =新CursorLoader(getActivity()
                                            MyContentProvider.ARTICLES_URI,
                                            空值,
                                            ArticlesContentHelper.ARTICLES_WHERE,
                                            ArticlesContentHelper.ARTICLES_WHEREARGS,
                                            空值);
        }
        回报(cursorLoader);
    }
};


解决方案

同时实现监听器是一个非常糟糕的主意:

  02-19 17:46:25.139:E / AndroidRuntime(24886):致命异常:主要
02-19 17:46:25.139:E / AndroidRuntime(24886):java.lang.IllegalStateException:已经有一个听众注册
02-19 17:46:25.139:E / AndroidRuntime(24886):在android.content.Loader.registerListener(Loader.java:152)
02-19 17:46:25.139:E / AndroidRuntime(24886):在android.app.LoaderManagerImpl $ LoaderInfo.start(LoaderManager.java:273)
02-19 17:46:25.139:E / AndroidRuntime(24886):在android.app.LoaderManagerImpl.installLoader(LoaderManager.java:523)
02-19 17:46:25.139:E / AndroidRuntime(24886):在android.app.LoaderManagerImpl.createAndInstallLoader(LoaderManager.java:510)
02-19 17:46:25.139:E / AndroidRuntime(24886):在android.app.LoaderManagerImpl.initLoader(LoaderManager.java:563)

所以其实这个问题的答案是:

这是必要的不可以同时实现监听。

I have an application which is using Loaders to get at a database which is also being edited by an IntentService. I receive data from the Loader through a LoaderCallbacks implementation, which is working fine.

I am also using ContentResolver#notifyChange(Uri, ContentObserver) to trigger reload. However, this only works when I call Cursor#setNotificationUri(Uri) beforehand.

I can find no reference to the latter method in any documentation and it seems in fact this may be causing crashes: see also

IllegalStateException "attempt to re-open an already-closed object" in SimpleCursorAdapter from ContentProvider

However, without this call on the Cursor the LoaderCallbacks#onLoadFinished(Loader<Cursor>, Cursor) is only hit after the initial load, and not after the notification. Do I also need to implement an OnLoadCompleteListener to do, well, exactly the same thing?

ContentProvider query method:

class MyContentProvider extends ContentProvider {
//...

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        Cursor query = db.query(getTableName(uri), projection, selection, selectionArgs, null, null, sortOrder);
        query.setNotificationUri(getContext().getContentResolver(), uri);
        return query;
    }

//...
}

Typical LoaderCallbacks:

LoaderCallbacks<Cursor> mCallbacks = new LoaderCallbacks<Cursor>() {

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mArticleAdapter.swapCursor(null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        if(cursor.isClosed()) {
            Log.d(TAG, "CURSOR RETURNED CLOSED");
            Activity activity = getActivity();
            if(activity!=null) {
                activity.getLoaderManager().restartLoader(mFragmentId, null, mCallbacks);
            }
            return;
        }
        mArticleAdapter.swapCursor(cursor);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        triggerArticleFeed();
        CursorLoader cursorLoader = null;

        if(id == mFragmentId) {
            cursorLoader = new CursorLoader(getActivity(),
                                            MyContentProvider.ARTICLES_URI,
                                            null,
                                            ArticlesContentHelper.ARTICLES_WHERE,
                                            ArticlesContentHelper.ARTICLES_WHEREARGS,
                                            null);
        }
        return(cursorLoader);
    }
};

解决方案

Implementing both listeners is a very bad idea:

02-19 17:46:25.139: E/AndroidRuntime(24886): FATAL EXCEPTION: main
02-19 17:46:25.139: E/AndroidRuntime(24886): java.lang.IllegalStateException: There is already a listener registered
02-19 17:46:25.139: E/AndroidRuntime(24886):    at android.content.Loader.registerListener(Loader.java:152)
02-19 17:46:25.139: E/AndroidRuntime(24886):    at android.app.LoaderManagerImpl$LoaderInfo.start(LoaderManager.java:273)
02-19 17:46:25.139: E/AndroidRuntime(24886):    at android.app.LoaderManagerImpl.installLoader(LoaderManager.java:523)
02-19 17:46:25.139: E/AndroidRuntime(24886):    at android.app.LoaderManagerImpl.createAndInstallLoader(LoaderManager.java:510)
02-19 17:46:25.139: E/AndroidRuntime(24886):    at android.app.LoaderManagerImpl.initLoader(LoaderManager.java:563)

So in fact the answer to this question is:

It is necessary NOT to implement both listeners.

这篇关于是否有必要同时实现LoaderCallbacks和OnLoadCompleteListener获得在ContentProvider的变化的通知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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