gpt4 book ai didi

Android CursorLoader 不响应 ContentProvider 通知

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:58:35 25 4
gpt4 key购买 nike

我正在更新一个 Android 2.2 应用程序以使用 CursorLoader(使用 v4 兼容性库),我正在焦头烂额地试图理解为什么当内容提供者时 onLoadFinished 方法没有被调用通知与 CursorLoader 查询关联的内容发生变化。

CursorLoader 正在查询客户内容提供者。我的提供商在其查询方法中设置通知 URI:

cursor.setNotificationUri(getContext().getContentResolver(), uri);

并通知其插入/更新/删除方法的变化:

getContext().getContentResolver().notifyChange(uri, null);

我已经检查过这两种情况下的 URI 是否相同。以前我使用的是具有相同内容提供者的 ManagedQuery,查询的内容更新得很好,这让我认为内容提供者可能没问题。

我看过 LoaderCursorSupport例如,有趣的是,当我在我的 Nexus One 上运行它时,我没有看到它反射(reflect)了我对联系人姓名所做的更改(在示例应用程序和联系人应用程序之间切换)。应该是?如果是这样,是否存在一些我不知道的潜在问题?

最佳答案

我终于弄清楚了这件事,而且,就像往常一样,这对我来说是一个愚蠢的错误。我在我的 onLoadFinished() 方法中调用了 cursor.close() - 我使用返回的游标创建一个 ArrayAdapter(我需要在列表顶部手动插入一个项目)并且游标关闭是使用 ManagedQuery 的遗留物在迁移以使用 CursorLoader 之前。

在寻找这个的过程中,我创建了一个简单的测试类来显示书签列表并添加一个随机书签(使用选项菜单)。这按应有的方式工作,即在添加项目后调用 onLoadFinished() 。这是代码,以防对其他人有用:

package com.test;

import android.content.ContentValues;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Browser;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class CursorLoaderTestActivity extends FragmentActivity
{
private static final String TAG = CursorLoaderTestActivity.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);

FragmentManager fm = getSupportFragmentManager();

// Create the list fragment and add it as our sole content.
if (fm.findFragmentById(android.R.id.content) == null)
{
CursorLoaderListFragment list = new CursorLoaderListFragment();
fm.beginTransaction().add(android.R.id.content, list).commit();
}
}


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

// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;

// If non-null, this is the current filter the user has provided.
String mCurFilter;

@Override public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);

// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText("No data");

// We have a menu item to show in action bar.
setHasOptionsMenu(true);

// Create an empty adapter we will use to display the loaded data.
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] { Browser.BookmarkColumns.TITLE },
new int[] { android.R.id.text1}, 0);

setListAdapter(mAdapter);

// Start out with a progress indicator.
setListShown(false);

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

//@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
// Place an action bar item for searching.
MenuItem item = menu.add("Add Item");
//item.setIcon(android.R.drawable.ic_menu_search);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
}

@Override
public boolean onOptionsItemSelected (MenuItem item)
{
ContentValues cv=new ContentValues();
cv.put(Browser.BookmarkColumns.TITLE, "!AA " + System.currentTimeMillis());
cv.put(Browser.BookmarkColumns.URL, "http://test/");
cv.put(Browser.BookmarkColumns.BOOKMARK, 1);
getActivity().getContentResolver().insert(Browser.BOOKMARKS_URI, cv);
return true;
}

//columns to query
static final String[] PROJECTION = new String[] { Browser.BookmarkColumns.TITLE };


public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
Log.i(TAG, "onCreateLoader");

return new CursorLoader(getActivity(), Browser.BOOKMARKS_URI,
PROJECTION, null, null,
Browser.BookmarkColumns.TITLE + " ASC");
}

public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
Log.i(TAG, "onLoadFinished");

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

}

关于Android CursorLoader 不响应 ContentProvider 通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8919198/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com