




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android中内容观察者的使用- ContentObserver类详解/qinjuning/article/details/7047607更多应用详解: /qinjuning前言: 工作中,需要开启一个线程大量的查询某个数据库值发送了变化,导致的开销很大,后来在老大的指点下,利用了 ContentObserver完美的解决了该问题,感到很兴奋,做完之后自己也对ContentObserver做下总结。 ContentObserver内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于 数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器, 相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。 熟悉Content Provider(内容提供者)的应该知道,我们可以通过UriMatcher类注册不同类型的Uri,我们可以通过这些不同的 Uri来查询不同的结果。根据Uri返回的结果,Uri Type可以分为:返回多条数据的Uri、返回单条数据的Uri。注册/取消注册ContentObserver方法,抽象类ContentResolver类中的方法原型如下:public final voidregisterContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer) 功能:为指定的Uri注册一个ContentObserver派生类实例,当给定的Uri发生改变时,回调该实例对象去处理。 参数:uri需要观察的Uri(需要在UriMatcher里注册,否则该Uri也没有意义了) notifyForDescendents为false 表示精确匹配,即只匹配该Uri 为true 表示可以同时匹配其派生的Uri,举例如下: 假设UriMatcher 里注册的Uri共有一下类型: 1 、content:/com.qin.cb/student (学生) 2 、content:/com.qin.cb/student/# 3、content:/com.qin.cb/student/schoolchild(小学生,派生的Uri)假设我们当前需要观察的Uri为content:/com.qin.cb/student,如果发生数据变化的Uri为 content:/com.qin.cb/student/schoolchild ,当notifyForDescendents为 false,那么该ContentObserver会监听不到, 但是当notifyForDescendents 为ture,能捕捉该Uri的数据库变化。 observer ContentObserver的派生类实例public final voidunregisterContentObserver(ContentObserverobserver) 功能:取消对给定Uri的观察 参数: observer ContentObserver的派生类实例ContentObserver类介绍构造方法public voidContentObserver(Handlerhandler) 说明:所有 ContentObserver的派生类都需要调用该构造方法 参数:handler Handler对象。可以是主线程Handler(这时候可以更新UI 了),也可以是任何Handler对象。常用方法 voidonChange(boolean selfChange) 功能:当观察到的Uri发生变化时,回调该方法去处理。所有ContentObserver的派生类都需要重载该方法去处理逻辑。 参数:selfChange回调后,其值一般为false,该参数意义不大(我也不懂,理解方法最重要)。 另外两个方法,用处不大,我也不懂,大家参照SDK自行理解,冒昧了。 booleandeliverSelfNotifications() 说明:Returns true if this observer is interested in notifications for changes made through the cursor the observer is registered with. final voiddispatchChange(boolean selfChange)观察特定Uri的步骤如下: 1、 创建我们特定的ContentObserver派生类,必须重载父类构造方法,必须重载onChange()方法去处理回调后的功能实现 2、 利用context.getContentResolover()获得ContentResolove对象,接着调用registerContentObserver()方法去注册内容观察者 3、 由于ContentObserver的生命周期不同步于Activity和Service等,因此,在不需要时,需要手动的调用unregisterContentObserver()去取消注册。 好了,基本讲解就介绍到这儿了。下面给出小DEMO的简单说明: Demo中共有两个不同的ContentObserver派生类,如下: 1、用来观察系统是否改变了飞行模式状态, PS: 大家可以去SDK中查看该类:vider.Settings.System。该类封装了对设置模块下所有值的存取,比如: 飞行模式状态、蓝牙状态、屏幕亮度值等,并且提供了相应的Uri。2、观察系统的短信息数据发生了变化。当监听到短信数据发生变化时,查询所有已发送的短信并且显示出来。 短信的Uri共有一下几种:content:/sms/inbox 收件箱 content:/sms/sent已发送content:/sms/draft 草稿 content:/sms/outbox发件箱 (正在发送的信息)content:/sms/failed发送失败content:/sms/queued待发送列表 (比如开启飞行模式后,该短信就在待发送列表里)关于短信的更多内容可以参考该博客: 当开启飞行模式和发送短信后(注意:使用Home键退出,而不是Back键),DMEO截图如下:DEMO文件如下:1、 观察飞行模式状态的ContentObserver派生类,AirplaneContentObserver.javajavaview plaincopyprint?1. packagecom.qin.contentobserver;2. 3. importandroid.content.Context;4. importandroid.database.ContentObserver;5. .Uri;6. importandroid.os.Handler;7. vider.*;8. vider.Settings.SettingNotFoundException;9. importandroid.util.Log;10. 11. 12. /用来观察system表里飞行模式所在行是否发生变化,“行”内容观察者13. publicclassAirplaneContentObserverextendsContentObserver14. 15. privatestaticStringTAG=AirplaneContentObserver;16. 17. privatestaticintMSG_AIRPLANE=1;18. 19. privateContextmContext;20. privateHandlermHandler;/此Handler用来更新UI线程21. 22. publicAirplaneContentObserver(Contextcontext,Handlerhandler)23. super(handler);24. mContext=context;25. mHandler=handler;26. 27. 28. /*29. *当所监听的Uri发生改变时,就会回调此方法30. *31. *paramselfChange此值意义不大一般情况下该回调值false32. */33. Override34. publicvoidonChange(booleanselfChange)35. Log.i(TAG,-theairplanemodehaschanged-);36. 37. /系统是否处于飞行模式下38. try39. intisAirplaneOpen=Settings.System.getInt(mContext.getContentResolver(),Settings.System.AIRPLANE_MODE_ON);40. Log.i(TAG,isAirplaneOpen-+isAirplaneOpen);41. mHandler.obtainMessage(MSG_AIRPLANE,isAirplaneOpen).sendToTarget();42. 43. catch(SettingNotFoundExceptione)44. /TODOAuto-generatedcatchblock45. e.printStackTrace();46. 47. 48. 49. 50. 2、观察系统里短消息的数据库变化的ContentObserver派生类,SMSContentObserver.javajavaview plaincopyprint?1. packagecom.qin.contentobserver;2. 3. importandroid.content.Context;4. importandroid.database.ContentObserver;5. importandroid.database.Cursor;6. .Uri;7. importandroid.os.Handler;8. importandroid.util.Log;9. 10. 11. /用来观察系统里短消息的数据库变化”表“内容观察者,只要信息数据库发生变化,都会触发该ContentObserver派生类12. publicclassSMSContentObserverextendsContentObserver13. privatestaticStringTAG=SMSContentObserver;14. 15. privateintMSG_OUTBOXCONTENT=2;16. 17. privateContextmContext;18. privateHandlermHandler;/更新UI线程19. 20. publicSMSContentObserver(Contextcontext,Handlerhandler)21. super(handler);22. mContext=context;23. mHandler=handler;24. 25. /*26. *当所监听的Uri发生改变时,就会回调此方法27. *28. *paramselfChange此值意义不大一般情况下该回调值false29. */30. Override31. publicvoidonChange(booleanselfChange)32. Log.i(TAG,thesmstablehaschanged);33. 34. /查询发件箱里的内容35. UrioutSMSUri=Uri.parse(content:/sms/sent);36. 37. Cursorc=mContext.getContentResolver().query(outSMSUri,null,null,null,datedesc);38. if(c!=null)39. 40. Log.i(TAG,thenumberofsendis+c.getCount();41. 42. StringBuildersb=newStringBuilder();43. /循环遍历44. while(c.moveToNext()45. /sb.append(发件人手机号码:+c.getInt(c.getColumnIndex(address)46. /.append(信息内容:+c.getInt(c.getColumnIndex(body)47. /.append(是否查看:+c.getInt(c.getColumnIndex(read)48. /.append(发送时间:+c.getInt(c.getColumnIndex(date)49. /.append(n);50. sb.append(发件人手机号码:+c.getInt(c.getColumnIndex(address)51. .append(信息内容:+c.getString(c.getColumnIndex(body)52. .append(n);53. 54. c.close();55. mHandler.obtainMessage(MSG_OUTBOXCONTENT,sb.toString().sendToTarget();56. 57. 58. 59. 3、主工程逻辑为MainActivity.java,对短消息的观察Uri,通过测试我发现只能监听此Uri “content:/sms” (等同于content:/sms/),而不能监听其他的Uri,比如content:/sms/outbox等。javaview plaincopyprint?1. packagecom.qin.contentobserver;2. 3. importandroid.app.Activity;4. importandroid.database.Cursor;5. .Uri;6. importandroid.os.Bundle;7. importandroid.os.Handler;8. importandroid.os.Message;9. vider.*;10. importandroid.util.Log;11. importandroid.widget.EditText;12. importandroid.widget.TextView;13. 14. publicclassMainActivityextendsActivity15. 16. privateTextViewtvAirplane;17. privateEditTextetSmsoutbox;18. 19. /Message类型值20. privatestaticfinalintMSG_AIRPLANE=1;21. privatestaticfinalintMSG_OUTBOXCONTENT=2;22. 23. privateAirplaneContentObserverairplaneCO;24. privateSMSContentObserversmsContentObserver;25. 26. /*Calledwhentheactivityisfirstcreated.*/27. Override28. publicvoidonCreate(BundlesavedInstanceState)29. super.onCreate(savedInstanceState);30. setContentView(R.layout.main);31. 32. tvAirplane=(TextView)findViewById(R.id.tvAirplane);33. etSmsoutbox=(EditText)findViewById(R.id.smsoutboxContent);34. 35. /创建两个对象36. airplaneCO=newAirplaneContentObserver(this,mHandler);37. smsContentObserver=newSMSContentObserver(this,mHandler);38. 39. /注册内容观察者40. registerContentObservers();41. 42. 43. privatevoidregisterContentObservers()44. /通过调用getUriFor方法获得system表里的飞行模式所在行的Uri45. UriairplaneUri=Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON);46. /注册内容观察者47. getContentResolver().registerContentObserver(airplaneUri,false,airplaneCO);48. /”表“内容观察者,通过测试我发现只能监听此Uri-content:/sms49. /监听不到其他的Uri比如说content:/sms/outbox5
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 高中美术鉴赏高一年级(人美版)教学设计:第7课 是什么使美术作品如此的千姿百态-分析理解美术作品的
- 四年级信息技术上册 第8课 收集精美的图片说课稿1
- 福建省南安市体育学校九年级化学下册 第十二单元 课题1 人类重要的营养物质说课稿 新人教版
- 消防监控方向知识培训课件
- 4.1立体图形与平面图形说课稿2024-2025学年湘教版数学七年级上册
- 消防物理灭火知识培训课件
- 写字楼业主装修管理制度流程
- 2025年高端童装行业需求分析及创新策略研究报告
- 2025年口腔医疗器械行业前景分析及投资机遇研究报告
- 2025年空气压缩机行业前景分析及投资机遇研究报告
- 企业信息化项目建设进度和成果汇报课件
- 高等数学期末试卷及答案
- 从0开始跨境电商-第三章-阿里巴巴国际站入门-OK
- 新能源电站远程监控系统建设方案
- 《紫藤萝瀑布》《丁香结》《好一朵木槿花》
- 2023柔性棚洞防护结构技术规程
- 河流地貌的发育 - 侵蚀地貌
- 离网光伏发电系统详解
- 广告文案写作(第二版)全套教学课件
- 《国家电网公司电力安全工作规程(配电部分)》
- 金融学黄达ppt课件9.金融市场
评论
0/150
提交评论