之前写过一篇文章《Android学习小Demo(13)Android中关于ContentObserver的使用》,在里面利用ContentOberver去监測短信URI内容的变化。我们先来回想一下,是怎样利用ContentOberver来监測短信内容的变化的。

1)要自己定义一个类,比方SmsContentObserver,继承ContentObserver,而且实现其onChange方法。

2)在onChange方法中去查询相应Uri,比方短信收件箱的内容,并将相应的记录利用Handler发送到主界面。

3)在主界面Activity中,要创建一个SmsContentObserver,而且将其注冊到ContentReslover中去。

4)在主界面Activity的Handler中获得在SmsContentObserver中变化的消息,更新主界面。

总的来说,过程就大概是这样,大家有兴趣能够看一下这一篇文章。

而本文介绍的是第二种方法,利用Loader来实现差点儿相同的效果,既然可以说效果差点儿相同,那么就说明了Loader有一个跟ContentObserver一样的特性,没错,它可以检測到相应内容的变化,事实上原因就在于Loader内部已经帮我们实现了一个ContentObserver,所以不须要我们再自己去实现。

先简单说一下什么是Loader。

Loader是Android在3.0之后才引进的一个类,其主要目的在于让Android跟Data之间的交互变得更加简单和高效,概括起来,我认为其功能有下面两点:

1)动态监測所处理对象状态的变化,大部分情况下是处理数据,但我认为仅仅是一方面。

2)当界面变化,须要被又一次创建的时候,它们可以又一次load到上一次的数据,而不须要再又一次进行查询。

当然,它还是异步的,也就意味着不会堵塞到主界面的显示,只是这个功能非常多其它的辅助类都有,也就不算啥特点了。

而正是到其第一点的特性,才让我们有机会能够不用那么麻烦去实现一个ContentObserver,而转而来利用Loader来实现同样的功能。

这一次我们做一个展示短信的Demo。当我们打开手机中的短信应用的时候,假设这个时候有新短信进来,我们会看到新短信立即就显示在界面上的,而我们这个Demo也正是如此效果,详细请看(截图大了点,莫怪)。

从上图中能够看到,当我们点击Sendbutton的时候,短信发过去,ListView中立即就显示出来刚刚发送的短信。

那么应该怎么使用Loader呢,我们以下来看代码吧。

1)因为Loader是3.0之后才引进来的,所以在3.0之前,假设我们想要使用Loader的时候,主Activity必需要继承FragmentActivity,才可以拿到LoaderManager。

2)要实现LoaderManager的内部接口LoaderCallbacks<D>,这是一个泛型接口,其定义例如以下:

public interface LoaderCallbacks<D> {/*** Instantiate and return a new Loader for the given ID.** @param id The ID whose loader is to be created.* @param args Any arguments supplied by the caller.* @return Return a new Loader instance that is ready to start loading.*/public Loader<D> onCreateLoader(int id, Bundle args);/*** ...* @param loader The Loader that has finished.* @param data The data generated by the Loader.*/public void onLoadFinished(Loader<D> loader, D data);/*** Called when a previously created loader is being reset, and thus* making its data unavailable.  The application should at this point* remove any references it has to the Loader's data.** @param loader The Loader that is being reset.*/public void onLoaderReset(Loader<D> loader);}

所以,我们代码中的第一步就是要实现这个接口,例如以下:

public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor>{...private Uri uri = Uri.parse("content://sms/inbox");...@Overridepublic Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {String[] projection = new String[] {"_id","address","body","type"};return new CursorLoader(this, uri, projection, null, null, "date desc");}@Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {mAdapter.swapCursor(cursor);}@Overridepublic void onLoaderReset(Loader<Cursor> arg0) {// TODO Auto-generated method stub}

3)要定义一个Uri,由于Loader它必需要从某个地方load数据,而这个Demo中,我们要获取的是收件箱的短信,所以在这里就是拿sms/inbox了。

4)在OnCreateLoader方法中,要创建一个CursorLoader。CursorLoader是AsyncTaskLoader的一个子类,所以它是一个异步的Loader,不会影响到主界面的展示。

5)在OnLoadFinished方法中,对Load完回来存放在cursor的数据进行处理。

上面的接口,仅仅是实现的方式而已,而当调用以下这种方法的时候,Loader才開始真正地发挥作用。在onCreate方法中,

    @Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);lvListView = (ListView) findViewById(R.id.lvListView);mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, new String[] {"address","body"}, new int[] {android.R.id.text1, android.R.id.text2});lvListView.setAdapter(mAdapter);getSupportLoaderManager().initLoader(LOADER_ID, null, this);}

因为我们是用的support包,所以须要用getSupportLoaderManager类来调用initLoader方法,此方法有三个參数:

a)id,因为一个Activity或者Fragment仅仅有一个LoaderManager,可是一个LoaderManager能够有多个Loader,用来处理不同的数据,所以id在这里能唯一地确定是哪个Loader。

b)bundle,这是传给LoaderManager的參数集合。

c)这是一个LoaderCallbacks的实现类,在这个Demo中,就是此Activity,所以就是this。

6)当调用getSupportLoaderManager().initLoader()方法的时候,Android首先会依据 id 去推断是否已经存在这种一个loader了,假设存在的话,它就会直接使用已有的loader,而不会去创建一个新的,也就是说,它不会去调用接口方法中的onCreateLoader方法了。而假设不存在相应 id 的Loader,则会去调用onCreateLoader方法,并实例化一个新的Loader出来。

而当相应 id 的loader已经存在的时候,Android会直接load数据,而接口方法中的onLoadFinished也会在数据load完之后立即被调用,这样就会存在一种情况,假设在onLoadFinished方法中使用的变量是在onCreateLoader中才初始化的,那么这个变量根本都没被初始化,就被使用了,程序就会报错了,所以在实际开发中,要考虑到这样一种情况的存在,在 onLoadFinished方法中,要做好一些推断。

最后另一个onLoaderReset方法,没有被用到,这种方法主要是在Loader不再被使用的时候,被关闭了等情况下,用来释放对Loader的使用的,比方在这个Demo中,假设loader不再用了,那么我们的Adpater就不应该再关联相应的cursor了,那么就能够在这里进行推断。

结束!源码下载。

Android学习小Demo(19)利用Loader来实时接收短信相关推荐

  1. Android学习小Demo(10)ToDoList的改进版之ViewPager显示多个图片

    在TodoList增强版的增加界面上,为了显示图片,我是挖了两块地方,放了两个ImageButton,来显示图片,而且限制了最多只能放两张图片.当两个View都放置图片之后,我就会把"Gal ...

  2. Android学习小Demo(10)ToDoList的加强版

    前两天去超市逛东西,问老板娘这个东西多少钱,那个东西多少钱,但是一两分钟后就搞混了,当时就想,我不是写了一个todo的吗,可以再拍照放上去,这样就有对比啦! 于是兴冲冲地赶回家,把功能给实现了,虽然这 ...

  3. Android学习小Demo(9)一个To Do List的实现

    记得看过一篇文章,是说一个人临走之前,列下了想做的最后100件事情,然后拿着这张便签,一件一件地去实现.又想起乔布斯说,如果今天是你的最后一天,你会怎么过? 我有很多事情想做,想写很多的文章,但是时间 ...

  4. Android学习小Demo(13)Android中关于ContentObserver的使用

    在一些应用上,比如手机银行,QQ,微信等,很多时候我们都需要通过发送验证码到手机上,然后把验证码填上去,然后才能成功地继续去做下面一步事情. 而如果每次我们都要离开当前界面,然后去查收短信,记住验证码 ...

  5. Android学习小Demo(12)TodoList实现ListView的分组实现

    很多情况下, 我们想要ListView上面展示的东西是可以分组的,比如联系人列表,国家列表啊,这样看起来数据的展现比较有层次感,而且也有助于我们快速定位到某一个具体的条目上,具体效果请看下图: 这是前 ...

  6. Android学习小Demo(11)一个显示行线的自定义EditText

    今天在处理一个EditText的时候,想着把EditText做成像一本作业本上的纸一样,每一行都可以由线条隔开,具体效果如下: 1)最开始的思路 一开始的想法是很简单的,找出每一行的高度,然后一行一行 ...

  7. Android学习小Demo(14)Android中关于PopupWindow的使用

    在一些场景中,我们希望能够点击按钮, 然后弹出一个菜单,而这个菜单是显示在屏幕的中央的,那么在Android中可以通过PopupWindow来实现这个效果. 具体效果如下图: 如上图中,我们点击&qu ...

  8. Android使用BroadCastRecevier广播实现接收短信,并利用Toast弹出显示内容

    在上一篇文章 Android简单实现BroadCastReceiver广播机制 中简单的实现了一个广播机制,这里利用BroadCarstRecevier实现一个接收短信并显示内容的案例,当然至于接收到 ...

  9. 神经网络学习小记录19——微调VGG分类模型训练自己的数据(猫狗数据集)

    神经网络学习小记录19--微调VGG分类模型训练自己的数据(猫狗数据集) 注意事项 学习前言 什么是VGG16模型 VGG模型的复杂程度 训练前准备 1.数据集处理 2.创建Keras的VGG模型 3 ...

  10. 神经网络学习小记录2——利用tensorflow构建循环神经网络(RNN)

    神经网络学习小记录2--利用tensorflow构建循环神经网络(RNN) 学习前言 RNN简介 tensorflow中RNN的相关函数 tf.nn.rnn_cell.BasicLSTMCell tf ...

最新文章

  1. pytorch model.train() 开启batchnormalize 和 dropout model.eval() 则会关闭dropout
  2. php请求路由,PHP 新手入门指南 - 表单请求与路由
  3. 【小米3使用经验】小米3联通版 miui7.2.11稳定版刷机
  4. python写魔兽世界脚本_用python bat写软件安装脚本 + HM NIS Edit自动生成软件安装脚本...
  5. access开发精要(13)-货币与数字类型格式(1)
  6. 《黑马程序员》 流程控制(C语言)
  7. [剑指offer]面试题第[68-2]题[Leetcode][第236题][JAVA][二叉搜索树的最近公共祖先][递归]
  8. javascript 校验 非空_Javascript的表单与验证-非空验证
  9. PHP获取字符串的所有子集,PHP Regexp(PCRE)-查找所有子字符串的集合
  10. hadoop和spark的区别和联系
  11. 手机端整张显示出来_现在动辄就4500万像素,像素越高显示效果真的越好吗?...
  12. mysql syncrelaylog_MySQL 5.7复制延迟之sync_relay_log
  13. xp-80c打印机无法打印_6种方法解决打印机无法打印问题
  14. GPS卫星星历与历书
  15. java毕业设计——基于java+AngularJS+jsp的配件营销系统设计与实现(毕业论文+程序源码)——配件营销系统
  16. python_pygame_alpha-beta剪枝算法_玩中国象棋
  17. 如何进行坡度坡向分析教程
  18. 如何用html5绘制圆形图片,javascript – 如何使用html5画布绘制连续的圆形图案
  19. vue-aMap高德地图的应用(添加覆盖物点坐标、自定义图标、添加信息窗体信息等)
  20. 在手机上玩魔兽争霸2

热门文章

  1. 安装python3.7的步骤_如何在Debian 9上安装Python 3.7?
  2. python itchat模块登录失败_itchat模块的不明错误
  3. myeclipse导入项目中文乱码_建立一个可烧录的空项目
  4. Centos开机自动执行shell脚本启动tomcat服务器
  5. android 利用cmdline,将參数从preloader传递到kernel
  6. 【重新挂载磁盘空间】Linux系统/home的磁盘空间重新挂载给/root
  7. java8 新特性实践
  8. Java千百问_05面向对象(008)_java中覆盖是什么
  9. Windows7中被大家忽略的实用七大功能
  10. SQLHelp sql数据库的DAL