我一直在为此奋斗一段时间。在我的项目中有几个活动包括一个ListView和一个扩展BaseAdapter的自定义适配器。他们还实现了一些通常会告诉它数据已经改变的接口。但是,当我从我的类中实现的侦听器/接口方法调用notifyDataSetChanged()时,ListView不会更新,并且不会调用任何适配器方法(getCount(),getView())。我知道这与notifyDataSetChanged()被调用的事实有关,我的意思是哪个线程,但我不太了解它,并找不到这种行为的直接解释。从侦听器回调方法调用Android的BaseAdapter notifyDataSetChanged()
作为这个问题的解决方法,我使用了一个Handler,它周期性地调用一个方法,并且在那个方法中,我看看布尔值'needsToBeUpdated'的值是否为真,然后我调用notifyDataSetChanged()方法。不过,这很丑陋,我相信需要有一种方法可以异步执行。
任何帮助,将不胜感激。
public class FriendsActivity extends Activity implements FriendsListener {
private ListView mListView;
private ArrayList<Friends> mFriendsList;
private FriendsAdapter mFriendsAdapter;
private boolean mNeedsToBeUpdated;
private Handler mListUpdateHandler;
private Runnable mListUpdateTask;
onCreate() {
initViews();
mFriendsAdapter = new FriendsAdapter(mFriendsList);
mListView.setAdapter(mFriendsAdapter);
SomeStaticClass.addFriendListener(this)
mNeedsToBeUpdated = false;
mListUpdateHandler = new Handler();
mListUpdateHandler.removeCallbacks(mListUpdateTask);
mListUpdateHandler.postDelayed(mListUpdateTask, 10000);
}
onListenerMethod() {
updateFriendsList();
mFriendsAdapter.updateDataSource(mFriendsList);
mFriendsAdapter.notifyDataSetChanged(); // THIS DOESN'T UPDATE THE VIEWS
mNeedsToBeUpdated = true;
}
protected void onResume() {
mListUpdateTask = new Runnable() {
public void run() {
if (mNeedsToBeUpdated) {
updateFriendsList();
mFriendsAdapter.updateDataSource(mFriendsList);
mFriendsAdapter.notifyDataSetChanged(); // THIS UPDATES THE VIEWS
mListsRequireUpdating = false;
}
mListUpdateHandler.postDelayed(mListUpdateTask, 10000);
}
};
mListUpdateHandler = new Handler();
mListUpdateHandler.removeCallbacks(mListUpdateTask);
mListUpdateHandler.post(mListUpdateTask);
super.onResume();
}
编辑:什么我谈论的
伪代码。当然,我花了几乎没有时间去寻找答案,一旦我张贴了这个在这里...
我恨做到这一点,但我多放些精力来寻找一个答案,我想我发现它得益于此:http://developer.android.com/resources/articles/painless-threading.html - 这:http://developer.android.com/reference/android/os/Handler.html
的解决方案是痛苦的简单。除了主/ UI线程之外,不可能在任何其他线程中更改UI。这就是为什么在回调方法中不起作用的原因。然而,在用户界面线程中创建一个处理程序(例如在onCreate()方法中)将其连接到UI线程,稍后可用于将事件发布到该线程。
mListUpdateHandler = new Handler();
然后,在完成UI调整的情况下,需要实现Runnable接口的内部类。
class UpdateListRunnable implements Runnable {
@Override
public void run() {
Log.i(LOGTAG, "UpdateListRunnable");
FriendsActivity.this.updateLists();
}
}
最后,在回调方法中,我们通过处理程序后与出UpdateListRunnable类的事件,主线程:到了upadteLists()方法是在UI线程中运行
@Override
public void entriesUpdated(Collection<String> entries) {
Log.i(LOGTAG, "entriesUpdated");
for (String entry : entries) {
Log.i(LOGTAG, "entry: " + entry);
}
mListUpdateHandler.post(new UpdateListRunnable());
}
谢谢一切都像魅力一样。