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) {

			}

		});

一般搜索框会有删除的×,我这里还有控制显示全选的框,效果如下:



在文本变化的时候会不断刷新列表,会调用searchList的方法,通过传递字符串来实现更新列表

通过lastest这个标识来解决线程同步问题,只有i跟lastest相等的时候采取刷新列表,其实这个办法并不土,不知道网友是否有更好的实现方法,麻烦指教一下。

	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();

	}


不知道以上解决方案有没有帮你解决问题,如果没有麻烦请告知一声。

下篇博客会介绍如何实现全选、反选、删除等功能,敬请期待。



  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小巫技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值