Filter

顺便看看,Android中过滤器是怎么实现的?

注释中提到,Filter一般通过继承Filterable实现

具体实现

这是SimpleAdapter出现的一个过滤首字母item的一个过滤器


  1. private class SimpleFilter extends Filter {
  2. @Override
  3. protected FilterResults performFiltering(CharSequence prefix) {
  4. FilterResults results = new FilterResults();
  5. if (mUnfilteredData == null) {
  6. mUnfilteredData = new ArrayList<Map<String, ?>>(mData);
  7. }
  8. if (prefix == null || prefix.length() == 0) {
  9. ArrayList<Map<String, ?>> list = mUnfilteredData;
  10. results.values = list;
  11. results.count = list.size();
  12. } else {
  13. String prefixString = prefix.toString().toLowerCase();
  14. ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData;
  15. int count = unfilteredValues.size();
  16. ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count);
  17. for (int i = 0; i < count; i++) {
  18. Map<String, ?> h = unfilteredValues.get(i);
  19. if (h != null) {
  20. int len = mTo.length;
  21. for (int j = 0; j < len; j++) {
  22. String str = (String) h.get(mFrom[j]);
  23. String[] words = str.split(" ");
  24. int wordCount = words.length;
  25. for (int k = 0; k < wordCount; k++) {
  26. String word = words[k];
  27. if (word.toLowerCase().startsWith(prefixString)) {
  28. newValues.add(h);
  29. break;
  30. }
  31. }
  32. }
  33. }
  34. }
  35. results.values = newValues;
  36. results.count = newValues.size();
  37. }
  38. return results;
  39. }
  40. @Override
  41. protected void publishResults(CharSequence constraint, FilterResults results) {
  42. //noinspection unchecked
  43. mData = (List<Map<String, ?>>) results.values;
  44. if (results.count > 0) {
  45. notifyDataSetChanged();
  46. } else {
  47. notifyDataSetInvalidated();
  48. }
  49. }
  50. }

通过performFiltering处理Result和publishResults返回数据进行刷新。

Filter抽象类源码

抽象类Filter中filter开启了对于数据的异步过滤操作。

寻找一下调用,发现AbsListView和AutoCompleteTextView 都有调用:

Abs中:


  1. // 判断类型
  2. if (mAdapter instanceof Filterable) {
  3. Filter f = ((Filterable) mAdapter).getFilter();
  4. // Filter should not be null when we reach this part
  5. if (f != null) {
  6. f.filter(s, this);
  7. } else {
  8. throw new IllegalStateException("You cannot call onTextChanged with a non "
  9. + "filterable adapter");
  10. }
  11. }

Auto中:


  1. protected void performFiltering(CharSequence text, int keyCode) {
  2. mFilter.filter(text, this);
  3. }

filter的调用通过一个限制词和接口,接口判断完成百分比。

filter:


  1. public final void filter(CharSequence constraint, FilterListener listener) {
  2. // 锁
  3. synchronized (mLock) {
  4. if (mThreadHandler == null) {
  5. // 开一个线程进行 这个线程自带Looper
  6. HandlerThread thread = new HandlerThread(
  7. THREAD_NAME, android.os.Process.THREAD_PRIORITY_BACKGROUND);
  8. thread.start();
  9. mThreadHandler = new RequestHandler(thread.getLooper());
  10. }
  11. final long delay = (mDelayer == null) ? 0 : mDelayer.getPostingDelay(constraint);
  12. // 回收池拿一个msg
  13. Message message = mThreadHandler.obtainMessage(FILTER_TOKEN);
  14. // 包含了过滤的一切信息的对象
  15. RequestArguments args = new RequestArguments();
  16. // make sure we use an immutable copy of the constraint, so that
  17. // it doesn't change while the filter operation is in progress
  18. args.constraint = constraint != null ? constraint.toString() : null;
  19. args.listener = listener;
  20. message.obj = args;
  21. // 移除了之前未处理的消息
  22. mThreadHandler.removeMessages(FILTER_TOKEN);
  23. mThreadHandler.removeMessages(FINISH_TOKEN);
  24. mThreadHandler.sendMessageDelayed(message, delay);
  25. }
  26. }

处理request的handler:


  1. private class RequestHandler extends Handler {
  2. public RequestHandler(Looper looper) {
  3. super(looper);
  4. }
  5. /**
  6. * <p>Handles filtering requests by calling
  7. * {@link Filter#performFiltering} and then sending a message
  8. * with the results to the results handler.</p>
  9. *
  10. * @param msg the filtering request
  11. */
  12. public void handleMessage(Message msg) {
  13. int what = msg.what;
  14. Message message;
  15. switch (what) {
  16. case FILTER_TOKEN:
  17. RequestArguments args = (RequestArguments) msg.obj;
  18. try {
  19. // 处理过程
  20. args.results = performFiltering(args.constraint);
  21. } catch (Exception e) {
  22. args.results = new FilterResults();
  23. Log.w(LOG_TAG, "An exception occured during performFiltering()!", e);
  24. } finally {
  25. // 返回值
  26. message = mResultHandler.obtainMessage(what);
  27. message.obj = args;
  28. message.sendToTarget();
  29. }
  30. // 结束调用
  31. synchronized (mLock) {
  32. if (mThreadHandler != null) {
  33. Message finishMessage = mThreadHandler.obtainMessage(FINISH_TOKEN);
  34. mThreadHandler.sendMessageDelayed(finishMessage, 3000);
  35. }
  36. }
  37. break;
  38. case FINISH_TOKEN:
  39. synchronized (mLock) {
  40. if (mThreadHandler != null) {
  41. mThreadHandler.getLooper().quit();
  42. mThreadHandler = null;
  43. }
  44. }
  45. break;
  46. }
  47. }
  48. }

处理结果的Handler:


  1. private class ResultsHandler extends Handler {
  2. /**
  3. * <p>Messages received from the request handler are processed in the
  4. * UI thread. The processing involves calling
  5. * {@link Filter#publishResults(CharSequence,
  6. * android.widget.Filter.FilterResults)}
  7. * to post the results back in the UI and then notifying the listener,
  8. * if any.</p>
  9. *
  10. * @param msg the filtering results
  11. */
  12. @Override
  13. public void handleMessage(Message msg) {
  14. RequestArguments args = (RequestArguments) msg.obj;
  15. // 返回数据
  16. publishResults(args.constraint, args.results);
  17. if (args.listener != null) {
  18. int count = args.results != null ? args.results.count : -1;
  19. args.listener.onFilterComplete(count);
  20. }
  21. }
  22. }

Android源码阅读-Filter过滤器的更多相关文章

  1. SpringMVC源码阅读:过滤器

    1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...

  2. Android源码阅读 – Zygote

    @Dlive 本文档: 使用的Android源码版本为:Android-4.4.3_r1 kitkat (源码下载: http://source.android.com/source/index.ht ...

  3. Android拓展系列(11)--打造Windows下便携的Android源码阅读环境

    因为EXT和NTFS格式的差异,我一直对于windows下阅读Android源码感到不满. 前几天,想把最新的android5.0的源码下下来研究一下,而平时日常使用的又是windows环境,于是专门 ...

  4. tomcat源码阅读之过滤器

    一.Servlet过滤器: 1.介绍: Servlet过滤器本身并不生成请求和响应对象,它只提供过滤作用. Servlet过滤器能够在Servlet被调用之前检查Request对象,修改Request ...

  5. Android源码阅读技巧--查找开发者选项中显示触摸操作源码

    在开发者模式下,在开发者选项中,可以勾选“显示触摸操作”,然后只要点击屏幕就会在点击的位置有圈圈显示.如何找到绘制圈圈的代码部分,有什么技巧来阅读代码量这么大的android系统源码呢?以下请跟着小老 ...

  6. Android 源码阅读之SMS,MMS

    主界面: com.android.mms.ui.ConversationList.java  [extends ListActivity] 点击新建信息:onListItemClick -〉 posi ...

  7. Android源码阅读笔记二 消息处理机制

    消息处理机制: .MessageQueue: 用来描述消息队列2.Looper:用来创建消息队列3.Handler:用来发送消息队列 初始化: .通过Looper.prepare()创建一个Loope ...

  8. Android 源码阅读笔记

    Zygote: .Zygote 是系统启动之后创建的第二个进程2.Zygote 创建zygote Socket.虚拟机3.Zygote 在虚拟机中通过forkSystemServer, 创建Serve ...

  9. 【安卓本卓】Android系统源码篇之(一)源码获取、源码目录结构及源码阅读工具简介

    前言        古人常说,“熟读唐诗三百首,不会作诗也会吟”,说明了大量阅读诗歌名篇对学习作诗有非常大的帮助.做开发也一样,Android源码是全世界最优秀的Android工程师编写的代码,也是A ...

随机推荐

  1. 服务器Config文件不能查看的问题

      由于某种需求,需要从IIS发布的服务中下载扩展名为config的文件,但是发布文件后,在浏览器无法查看文件.根据反馈的的错误提示,大致说config属于配置文件,处于安全考虑,不能随便浏览. 如果 ...

  2. 在Windows Server 2012 R2的Hyper-V中设置虚拟机启用增强会话模式

    在Windows Server 2012 R2的Hyper-V中,可以为虚拟机提供一种全新的连接方式,就是“增强会话模式”,它将让您更加方便的对虚拟机进行操作,比如分辨率的调整.设备的加载,最为方便的 ...

  3. Spring.Net简单用法

    Spring.Net其实就是抽象工厂,只不过更加灵活强大,性能上并没有明显的区别. 它帮我们实现了控制反转. 其有两种依赖注入方式. 第一:属性注入 第二:构造函数注入 首先,我们去  Spring. ...

  4. SpringMVC的工作原理

    1.首先浏览器发送请求给前端控制器DispatcherServlet,DispatcherSerlvet根据请求信息,基于一定的原则选择合适的控制器进行处理并把请求委托给它. 2.页面控制器接收到请求 ...

  5. python读取文件的方法

    一. 通过readline 逐行读取: #--encoding:utf-8 with open("ha.conf","r",encoding='utf-8') ...

  6. 如何使用Dubbo服务和集成Spring

    Dubbo是什么? Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点. Dubbo是一个 ...

  7. struts2的action是多例,servlet是单例

    struts2中action是多例的,即一个session产生一个action如果是单例的话,若出现两个用户都修改一个对象的属性值,则会因为用户修改时间不同,两个用户访问得到的 属性不一样,操作得出的 ...

  8. windows下新安装的mysql修改root password问题

    常用步骤: 1. 在my.ini中的mysqld下添加一行 skip-grant-tables 2.重启mysql后直接进入后,用SQL直接修改password列: C:\> net stop ...

  9. UDS(ISO14229-2006) 汉译(No.3术语与定义)

    下列术语适用于本文档. 3.1 integer 类型 定义正负整数的数据类型. 注:integer类型取值范围未在本文档定义. 3.2 diagnostic trouble code 由车载诊断系统获 ...

  10. 在多行列表中id同名的<a>标签点击事件处理方法

    Struts2标签 问题描述:最近项目中在使用struts迭代标签动态生成列表的过程中,由于每一行li元素中包含<a>超链接,如下图 一开始超链接是这样的<a href=“#” id ...