我一直在爲此奮鬥一段時間。在我的項目中有幾個活動包括一個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());
}
謝謝一切都像魅力一樣。