之前写过一篇文章《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");
...
@Override
public 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");
} @Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { mAdapter.swapCursor(cursor); } @Override
public 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方法中,

	@Override
protected 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一个显示行线的自定义EditText

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

  2. Android学习小Demo(20)关于Fragment的应用

    Android在3.0之后引入了Fragment的概念,我推測其想法可能仅仅是想更好地兼容大屏幕或者平板的开发,由于大屏幕能够展示很多其它的内容,而内容一多,逻辑有可能就乱,而利用Fragment,则 ...

  3. Android学习小Demo(21)ListView的联动选择

    在日常的App开发中,尤其是在开发生活服务的应用上,非常多时候,我们会须要联动地展现省市区的数据等,需求大概例如以下: 1)展现全部省份 2)当点击某省份的时候,在二级菜单上展现此省份以下所属的城市列 ...

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

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

  5. android学习十四(android的接收短信)

    收发短信是每一个手机主要的操作,android手机当然也能够接收短信了. android系统提供了一系列的API,使得我们能够在自己的应用程序里接收和发送短信. 事实上接收短信主要是利用我们前面学过的 ...

  6. 利用阿里大于接口发短信(Delphi版)

    阿里大于是阿里通信旗下产品,融合了三大运营商的通信能力,提供包括短信.语音.流量直充.私密专线.店铺手机号等个性化服务.每条四分五,价钱还算公道,经老农测试,响应速度非常快,基本上是秒到.官方文档提供 ...

  7. android接收短信——framework处理流程(android 5.1)

    modem层不懂,所以直接从RIL.java开始.以电信卡接收短信为例 modem通知RIL.java中的 RILReceiver处理接收信息 class RILReceiver implements ...

  8. Android接收短信

    Android收到短信时会广播android.provider.Telephony.SMS_RECEIVED消息,因此只要定义一个Receiver,收听该消息,就能接收短信. <receiver ...

  9. Android 接收短信

    启动程序时启动一个service,在service里注册接收短信的广播,当手机收到短信里,打印出短信内容跟电话号码. package com.lmy.SmsListener; import andro ...

随机推荐

  1. 2012 PHP热门资料64个+经典源码50个——下载目录 :

    完整附件0豆下载:http://down.51cto.com/data/419216 附件部分预览: PHP精彩应用实例程序源码集锦 http://down.51cto.com/zt/39 无师自通: ...

  2. POJ 1696 Space Ant(点积的应用)

    Space Ant 大意:有一仅仅蚂蚁,每次都仅仅向当前方向的左边走,问蚂蚁走遍全部的点的顺序输出.開始的点是纵坐标最小的那个点,開始的方向是開始点的x轴正方向. 思路:从開始点開始,每次找剩下的点中 ...

  3. TextView 使用自定义的字体和亮点

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/40478815 如今非常多应用中喜欢使用自己定义字体,今天我就来实如今TextView中使用自 ...

  4. 基础知识(1)- Java程序设计概述

    1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语  1.2.1 简单性  1.2.2 面向对象  1.2.3 网络技能  1.2.4 健壮性  1.2.5 安全性  1.2.6 体系 ...

  5. android贴士Toast

    转载请注明出处:http://blog.csdn.net/droyon/article/details/42009015 我们可以用androd提供toast控制,但在使用过程中,给我们发了很多Toa ...

  6. Android:What is ART?

    背景:Android4.2之前,安卓手机系统的应用程序均在Dalvik Java的虚拟机上执行,这样的执行模式还要依靠一个编译器来实现与应用程序的沟通.应用程序每次执行时,都须要将程序内的代码转变为机 ...

  7. vs修错小知识,相当于我自己的笔记,需要的人可以看下

    在出现这种外部错误时,首先得检查你自己的的类的方法是否都以及实现了,我就是出现没有实现某些方法所以报出这个错误!!! 结果是onExit()方法我定义了没有去实现它. (待续)

  8. Visual Studio 有哪些好用的插件?

    推荐一批绝大部分都是免费的能较好增强写代码舒适度的. .NET Demon -- (非免费)安装后可以连续编译, 如果不买License的话过期后也还有代码改动后自动保存的上好功能, 安装它之后再也不 ...

  9. 重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试

    原文:重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试 [源码下载] 重新想象 Windows 8 Store ...

  10. Sliverlight实例之 绘制扇形和环形图

    一,1道几何题 已知两点坐标确定一条直线,直线上存在一个未知点,起始点与未知点的距离已知 求:未知点坐标 思路,如下: 求AB长度,可以根据两点距离公式 二,写个C#类 定义一个Point类,代表坐标 ...