Android通訊錄開發之解決快速搜索聯系人線程同步問題

Android通訊錄開發之解決快速搜索聯系人線程同步問題

2013年1月13日

上一篇博客介紹的是如何實現搜索,在PhoneUtil中已經定義好瞭search方法,開發者直接拿來用就ok瞭,但用的時候肯定會遇到線程同步問題,如何解決搜索的時候UI線程卡頓的現象,這時候就需要另開一個線程來進行搜索操作瞭,但由於在搜索框輸入字符的時候,一般都是快速輸入的,這就會導致線程同步問題的出現,搜索出來的結果會不對。小巫由於經驗不足還有相關知識的欠缺,在遇到這個問題的時候一直沒能解決,所以隻能去請教有經驗的工程師瞭,最終也找到解決辦法。

在UI線程我們知道超過5秒的操作就會出現卡頓或者ANR對話框,所以一般費時的操作絕不能放在UI線程,但數據的更新和通知就要放在UI線程來實現瞭,比如ListView的adapter的數據更新就要在UI線程裡通知,不然就可能出現數據沒有得到即使更新的現象。

這些問題隻有在實際開發當中才會遇到,我廢話也不多說瞭,下面是解決方案。

搜索框,文本變化的監聽

searchEditText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(final CharSequence s, int start,
					int before, int count) {
				if (!TextUtils.isEmpty(s)) {
					btnClear.setVisibility(View.VISIBLE);
					selectAllBtn.setVisibility(View.GONE);
					searchList(s.toString());
				} else {// 如果輸入框內容為空,顯示全部
					btnClear.setVisibility(View.GONE);
					selectAllBtn.setVisibility(View.VISIBLE);
					searchList("");
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(final Editable s) {

			}

		});

一般搜索框會有刪除的×,我這裡還有控制顯示全選的框,效果如下:


vc7KzOKjrNa709BpuPpsYXN0ZXN0z+C1yLXEyrG68rLJyKHLotDCwdCx7aOsxuTKtdXiuPaw7LeosqKyu83Bo6yyu9aqtcDN+NPRyse38dPQuPy6w7XEyrXP1re9t6ijrMLpt7PWuL3M0rvPwqGjPC9wPgo8cD48cHJlIGNsYXNzPQ==”brush:java;”> private static int lastest = 0;

// 實現線程同步搜索聯系人
// 線程同步問題可能會導致數據顯示錯誤,比如會顯示上一次搜索到的數據
public void searchList(final String s) {
// 用戶可能正在快速輸入電話號碼,之前在搜索的聯系人列表已經過時瞭。
final int i = ++lastest;
// 開一個線程來進行快速搜索
new Thread(new Runnable() {

@Override
public void run() {
if (TextUtils.isEmpty(s)) {
// 如果輸入的字符串為空,則顯示所有聯系人
searchContacts = allContacts;
} else {
// searhContacts指向搜索返回的list
searchContacts = PhoneUtil.search(s, allContacts);
}

if (i == lastest) { // 避免線程同步問題
LocalContactActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
if (i == lastest) { // 避免線程同步問題
contactList.clear();
contactList.addAll(searchContacts);
refreshList();
}
}
});
}
}
}).start();
}
數據有更新,調用adapter的notifyDataSetChanged()方法就可以達到刷新列表效果。

	/** 刷新列表和確認按鈕 **/
	public void refreshList() {
		// adapter.setContactList(contactList);
		adapter.notifyDataSetChanged();
		refreshBtnOK();

	}

不知道以上解決方案有沒有幫你解決問題,如果沒有麻煩請告知一聲。

下篇博客會介紹如何實現全選、反選、刪除等功能,敬請期待。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *