我在更改'数据集'后尝试更新我的列表视图,但它没有,除非我手动刷新视图或刷新活动。 这不起作用:
runOnUiThread(new Runnable() {
public void run() {
entriesListAdapter.notifyDataSetChanged();
}
});
虽然这样做:
handler.postDelayed(new Runnable() {
@Override
public void run() {
onCreate(null);
entriesListAdapter.notifyDataSetChanged();
}
}, 1000);
但这绝对不是正确的做法。我使用notifydatasetchanged错了吗?
我的整个活动: 包app.wordpress;
import app.wordpress.service.FetcherService;
import someontherimports
public class EntriesListActivity extends ListActivity {
private static final int CONTEXTMENU_REFRESH_ID = 4;
private static final int CONTEXTMENU_MARKASREAD_ID = 6;
private static final int ACTIVITY_APPLICATIONPREFERENCES_ID = 1;
private static final Uri CANGELOG_URI = Uri.parse("http://wordpress.com");
private static final int CONTEXTMENU_MARKASUNREAD_ID = 7;
private static final int CONTEXTMENU_DELETE_ID = 8;
private static final int CONTEXTMENU_COPYURL = 9;
private static final int DIALOG_ABOUT = 7;
public static final String EXTRA_SHOWREAD = "show_read";
public static final String EXTRA_SHOWFEEDINFO = "show_feedinfo";
public static final String EXTRA_AUTORELOAD = "autoreload";
private static final String[] FEED_PROJECTION = {FeedData.FeedColumns.NAME,
FeedData.FeedColumns.URL,
FeedData.FeedColumns.ICON
};
private Uri uri;
private EntriesListAdapter entriesListAdapter;
private byte[] iconBytes;
@Override
protected void onCreate(Bundle savedInstanceState) {
if (MainTabActivity.isLightTheme(this)) {
setTheme(R.style.Theme_Light);
}
super.onCreate(savedInstanceState);
String title = null;
iconBytes = null;
Intent intent = getIntent();
long feedId = intent.getLongExtra(FeedData.FeedColumns._ID, 0);
if (feedId > 0) {
Cursor cursor = getContentResolver().query(FeedData.FeedColumns.CONTENT_URI(feedId), FEED_PROJECTION, null, null, null);
if (cursor.moveToFirst()) {
title = cursor.isNull(0) ? cursor.getString(1) : cursor.getString(0);
iconBytes = cursor.getBlob(2);
}
cursor.close();
}
if (!MainTabActivity.POSTGINGERBREAD && iconBytes != null && iconBytes.length > 0) { // we cannot insert the icon here because it would be overwritten, but we have to reserve the icon here
if (!requestWindowFeature(Window.FEATURE_LEFT_ICON)) {
iconBytes = null;
}
}
setContentView(R.layout.entries);
uri = intent.getData();
entriesListAdapter = new EntriesListAdapter(this, uri, intent.getBooleanExtra(EXTRA_SHOWFEEDINFO, false), intent.getBooleanExtra(EXTRA_AUTORELOAD, false));
setListAdapter(entriesListAdapter);
if (title != null) {
setTitle(title);
}
if (iconBytes != null && iconBytes.length > 0) {
int bitmapSizeInDip = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24f, getResources().getDisplayMetrics());
Bitmap bitmap = BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length);
if (bitmap != null) {
if (bitmap.getHeight() != bitmapSizeInDip) {
bitmap = Bitmap.createScaledBitmap(bitmap, bitmapSizeInDip, bitmapSizeInDip, false);
}
if (MainTabActivity.POSTGINGERBREAD) {
CompatibilityHelper.setActionBarDrawable(this, new BitmapDrawable(bitmap));
} else {
setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(bitmap));
}
}
}
if (RSSOverview.notificationManager != null) {
RSSOverview.notificationManager.cancel(0);
}
getListView().setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
menu.setHeaderTitle(((TextView) ((AdapterView.AdapterContextMenuInfo) menuInfo).targetView.findViewById(android.R.id.text1)).getText());
menu.add(0, CONTEXTMENU_REFRESH_ID, Menu.NONE, R.string.contextmenu_refresh);
menu.add(0, CONTEXTMENU_MARKASREAD_ID, Menu.NONE, R.string.contextmenu_markasread).setIcon(android.R.drawable.ic_menu_manage);
menu.add(0, CONTEXTMENU_MARKASUNREAD_ID, Menu.NONE, R.string.contextmenu_markasunread).setIcon(android.R.drawable.ic_menu_manage);
menu.add(0, CONTEXTMENU_DELETE_ID, Menu.NONE, R.string.contextmenu_delete).setIcon(android.R.drawable.ic_menu_delete);
menu.add(0, CONTEXTMENU_COPYURL, Menu.NONE, R.string.contextmenu_copyurl).setIcon(android.R.drawable.ic_menu_share);
}
});
}
@Override
protected void onListItemClick(ListView listView, View view, int position, long id) {
TextView textView = (TextView) view.findViewById(android.R.id.text1);
textView.setTypeface(Typeface.DEFAULT);
textView.setEnabled(false);
view.findViewById(android.R.id.text2).setEnabled(false);
entriesListAdapter.neutralizeReadState();
startActivity(new Intent(Intent.ACTION_VIEW, ContentUris.withAppendedId(uri, id)).putExtra(EXTRA_SHOWREAD, entriesListAdapter.isShowRead()).putExtra(FeedData.FeedColumns.ICON, iconBytes));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.entrylist, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(R.id.menu_group_0, entriesListAdapter.getCount() > 0);
return true;
}
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_markasread: {
new Thread() { // the update process takes some time
public void run() {
getContentResolver().update(uri, RSSOverview.getReadContentValues(), null, null);
}
}.start();
entriesListAdapter.markAsRead();
break;
}
case R.id.menu_markasunread: {
new Thread() { // the update process takes some time
public void run() {
getContentResolver().update(uri, RSSOverview.getUnreadContentValues(), null, null);
}
}.start();
entriesListAdapter.markAsUnread();
break;
}
case R.id.menu_hideread: {
if (item.isChecked()) {
item.setChecked(false).setTitle(R.string.contextmenu_hideread).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
entriesListAdapter.showRead(true);
} else {
item.setChecked(true).setTitle(R.string.contextmenu_showread).setIcon(android.R.drawable.ic_menu_view);
entriesListAdapter.showRead(false);
}
break;
}
case R.id.menu_deleteread: {
new Thread() { // the delete process takes some time
public void run() {
String selection = Strings.READDATE_GREATERZERO+Strings.DB_AND+" ("+Strings.DB_EXCUDEFAVORITE+")";
getContentResolver().delete(uri, selection, null);
FeedData.deletePicturesOfFeed(EntriesListActivity.this, uri, selection);
runOnUiThread(new Runnable() {
public void run() {
entriesListAdapter.getCursor().requery();
}
});
}
}.start();
break;
}
case R.id.menu_deleteallentries: {
Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.contextmenu_deleteallentries);
builder.setMessage(R.string.question_areyousure);
builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
new Thread() {
public void run() {
getContentResolver().delete(uri, Strings.DB_EXCUDEFAVORITE, null);
runOnUiThread(new Runnable() {
public void run() {
entriesListAdapter.getCursor().requery();
}
});
}
}.start();
}
});
builder.setNegativeButton(android.R.string.no, null);
builder.show();
break;
}
case CONTEXTMENU_MARKASREAD_ID: {
long id = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id;
getContentResolver().update(ContentUris.withAppendedId(uri, id), RSSOverview.getReadContentValues(), null, null);
entriesListAdapter.markAsRead(id);
break;
}
case CONTEXTMENU_MARKASUNREAD_ID: {
long id = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id;
getContentResolver().update(ContentUris.withAppendedId(uri, id), RSSOverview.getUnreadContentValues(), null, null);
entriesListAdapter.markAsUnread(id);
break;
}
case CONTEXTMENU_DELETE_ID: {
long id = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id;
getContentResolver().delete(ContentUris.withAppendedId(uri, id), null, null);
FeedData.deletePicturesOfEntry(Long.toString(id));
entriesListAdapter.getCursor().requery(); // he have no other choice
break;
}
case CONTEXTMENU_COPYURL: {
((ClipboardManager) getSystemService(CLIPBOARD_SERVICE)).setText(((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).targetView.getTag().toString());
break;
}
case R.id.menu_settings: {
startActivityForResult(new Intent(this, ApplicationPreferencesActivity.class), ACTIVITY_APPLICATIONPREFERENCES_ID);
break;
}
case R.id.menu_about: {
showDialog(DIALOG_ABOUT);
break;
}
case R.id.menu_refresh: {
new Thread() {
public void run() {
sendBroadcast(new Intent(Strings.ACTION_REFRESHFEEDS).putExtra(Strings.SETTINGS_OVERRIDEWIFIONLY, PreferenceManager.getDefaultSharedPreferences(EntriesListActivity.this).getBoolean(Strings.SETTINGS_OVERRIDEWIFIONLY, false)));
}
}.start();
runOnUiThread(new Runnable() {
public void run() {
entriesListAdapter.notifyDataSetChanged();
}
});
break;
}
}
return true;
}
@Override
protected void onResume()
{
super.onResume();
setProgressBarIndeterminateVisibility(isCurrentlyRefreshing());
registerReceiver(refreshReceiver, new IntentFilter("app.wordpress.REFRESH"));
}
@Override
protected void onPause()
{
unregisterReceiver(refreshReceiver);
super.onPause();
}
private BroadcastReceiver refreshReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
setProgressBarIndeterminateVisibility(true);
}
};
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch (id) {
case DIALOG_ABOUT: {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle(R.string.menu_about);
MainTabActivity.INSTANCE.setupLicenseText(builder);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setNeutralButton(R.string.changelog, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Intent.ACTION_VIEW, CANGELOG_URI));
}
});
return builder.create();
}
default: dialog = null;
}
return dialog;
}
private boolean isCurrentlyRefreshing()
{
ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
for (RunningServiceInfo service: manager.getRunningServices(Integer.MAX_VALUE)) {
if (FetcherService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
答案 0 :(得分:1)
您是指在Activity中使用此代码块吗?
case R.id.menu_refresh: {
new Thread() {
public void run() {
sendBroadcast(new Intent(Strings.ACTION_REFRESHFEEDS).putExtra(Strings.SETTINGS_OVERRIDEWIFIONLY, PreferenceManager.getDefaultSharedPreferences(EntriesListActivity.this).getBoolean(Strings.SETTINGS_OVERRIDEWIFIONLY, false)));
}
}.start();
runOnUiThread(new Runnable() {
public void run() {
entriesListAdapter.notifyDataSetChanged();
}
});
break;
如果是这样,问题可能是runOnUiThread()
的调用实际上并不在你创建的Thread
内,而是在主线程上调用。
这个代码的结构方式,在选择刷新后,创建后台线程来激发广播Intent
(不必要,BTW,因为这也是一个异步进程......它立即返回)然后notifyDataSetChanged()
之后会立即运行(因为runOnUiThread()
从主线程调用时会立即执行Runnable
。
所以你发送广播并在几乎同一时间更新适配器......没有多少时间可以在那段时间内实际改变。如果您希望sendBroadcast()
阻止并在某个接收方处理完之后返回,则情况并非如此。
答案 1 :(得分:0)
在你的contentProvider中,你应该调用contentResolver.notifyChange来通知适配器contentResolver提供的数据发生了变化,这将为你更新listView。