切换和层叠状态变化接收器以提高效率
2012-09-11 11:36
204 查看
http://developer.android.com/intl/zh-CN/training/monitoring-device-state/manifest-receivers.html#ToggleReceivers
监控连接情况的变化
只要连接的具体情况发生变化,ConnectivityManager就会广播
CONNECTIVITY_ACTION
(
"android.net.conn.CONNECTIVITY_CHANGE") 操作。您可以在清单中注册广播接收器,以便侦听这些变化并相应地恢复(或暂停)后台更新。
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
设备连接情况的变化可能会非常频繁,只要您在移动数据和 Wi-Fi 之间相互切换,系统就会触发此广播。因此比较合适的做法是,仅当之前暂停了更新或下载时才监控此广播,以便恢复更新或下载。通常,您只需在开始更新前检查互联网连接情况即可,如果未连接互联网,请暂停后续更新,直到连接恢复。
根据需要操作广播接收器
监控设备状态变化的最简单方法就是,为您监控的每种状态创建BroadcastReceiver并在应用清单中逐一进行注册。然后,您只需根据当前设备状态在每个接收器中重新安排重复提醒即可。
此方法的负面影响在于,只要系统触发了这些接收器中的任何一个,相关应用就会唤醒设备,其频率可能会远远超过所需的水平。
更好的方法是在运行时停用或启用广播接收器。这样的话,您就可以将自己在清单中声明的接收器用作被动提醒,只有在需要时才会由系统事件触发
切换和层叠状态变化接收器以提高效率
您可以使用PackageManager切换清单中定义的任意组件的启用状态(包括您要启用或停用的任意广播接收器),具体如以下片段所示:
ComponentName receiver = new ComponentName(context, myReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
在使用此技巧时,如果您确定连接已断开,就可以停用除连接变化接收器外的所有接收器。相反,成功连接后,您就可以停止侦听连接变化,同时只需在执行更新和重新安排重复更新提醒前查看是否在线即可。
您可以使用同样的方法来延迟需要较高带宽的下载任务。只有在连接 Wi-Fi 后,您才能直接启用用于侦听连接变化和启动下载任务的广播接收器。
setComponentEnabledSetting doesn't work on widget
PackageManager.setComponentEnabledSetting 可以用来禁用某个组件,包括activity,receiver等等。被禁用的组件会被持久化到/data/system/packages.xml中,如:
<package name="com.android.setupwizard" codePath="/system/app/SetupWizard.apk" nativeLibraryPath="/data/data/com.android.setupwizard/lib" flags="1" ft="13349457a90" it="13349457a90" ut="13349457a90" version="130" userId="10016">
<sigs count="1">
<cert index="0" />
</sigs>
<disabled-components>
<item name="com.android.setupwizard.SetupWizardActivity" />
</disabled-components>
</package>
现在需要在运行时禁用某个widget,同时有一个system property用来标识是否需要禁用。
因为widget实际上就是个reveiver,它接收android.appwidget.action.APPWIDGET_UPDATE的action,所以开始的思路是:
创建一个BroadcastReceiver,接收Intent.ACTION_BOOT_COMPLETED这个动作,从而在启动完成后调用SystemProperties.get("disable_widget"),如果需要禁用这个widget,那么调用:
PackageManager.setComponentEnabledSetting(widgetComponentName,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
但是问题是,调用这个方法disable掉这个widget后,发现必须把设备重启之后才能生效...
经过google,发现问题出在com.android.server.AppWidgetService.java。
原来开机后,SystemServer会调用AppWidgetService的systemReady()方法,这个方法通过PackageManager查询所有的widget receiver组件,保存到mInstalledProviders变量列表中,并持久化widget信息到/data/system/appwidgets.xml中。
而在Launcher上长按添加widget时的那个widget列表信息也是通过AppWidgetService取得mInstalledProviders列表。
问题在于我们通过PackageManager.setComponentEnabledSetting()禁用掉某个widget后,packagemanager确实将这个组件disable了,但是AppWidgetService却没有去从packagemanager reload widget信息,这就导致了mInstalledProviders中保存的widget信息还是开机时load进来的那些信息,并没有与pm进行同步。直到下一次开机调用systemReady重新加载widget信息才会刷新这个列表。
参考:
Dynamically enabling or disabling a widget with PackageManager.setComponentEnabledSetting does not work
http://code.google.com/p/android/issues/detail?id=6533 http://blog.csdn.net/yinlijun2004/article/details/6136108
相关文章推荐
- EJB通过ANT提高EJB应用程序的开发效率、无状态发展本地接口bean、开发状态bean
- android scrollview fragment viewpager 切换 状态 变化 scrollview 滚动到最上方
- windows mediaPlayer 图片切换(也适用其他插件的状态变化):
- Android TextView 状态切换时变化文字颜色
- [android] Activity 的生命周期 以及 横屏竖屏切换时 Activity 的状态变化
- 巧用Qt 设计师(Designer)提高工作效率之切换设计师控件显示模式
- 提高研发效率一,顺流状态
- EJB通过ANT提高EJB应用的开发效率、开发具有本地接口的无状态bean、开发有状态bean
- android Activity 的生命周期 以及横屏竖屏切换时 Activity 的状态变化
- EJB通过ANT提高EJB应用的开发效率、开发具有本地接口的无状态bean、开发有状态bean
- 利用shell脚本提高效率(切换用户不需要输入密码)
- [android] Activity 的生命周期 以及横屏竖屏切换时 Activity 的状态变化
- hdfs haadmin使用,DataNode动态上下线,NameNode状态切换管理,数据块的balance,HA下hdfs-api变化(来自学习资料)
- HTTP第二篇【HTTP方法、不保存状态、提高传输效率】
- Centos5.5几种提高工作效率的方法
- 能容入团队开发成员必备的优秀习惯,提高效率的小技巧
- 安卓图片切换和透明度增减变化alpha
- 54点提高PHP编程效率 引入缓存机制提升性能
- 使用数据库连接池提高执行效率
- IOS ARC内存管理,提高效率避免内存泄露