在android中开发widget控件的时候在appwidget-provider元素中有个属性android:updatePeriodMillis控制widget控件多长时间刷新一次,但是在1.6以后的版本中,谷歌从省电的方面考虑规定,当updatePeriodMillis的设置的值小于半个小时时,就会失效。也就是通过设置这个属性值,最短的更新间隔是半小时。但是我们有时候做的一些应用,比如时钟之类的必须要在极端的时间内刷新,必须另辟蹊径。网上流传的大都是这么几种方法:

1通过自己发送android.appwidget.action.APPWIDGET_UPDATE这个广播刷新,但是他会使所有的桌面widget控件刷新

 2 通过自己发送自定义的广播刷新

关键在于在哪里发送广播,有这么几种选择

1在OnEnable中开启定时线程发

2单开一个service发

3用alarm定时发

后两种是可行的,第一种方法虽然看起来可行但是有一个bug,如果不解决就会发现自己的widget在运行了一段时间后莫名其妙的的停止了运行。我当时发现总是过一段时间莫名其妙的停止运行后很苦恼,找不到原因,但是系统每半小时的android.appwidget.action.APPWIDGET_UPDATE广播还是能正常启动,后来在全局的logcat里发现停止运行前有一个进程向widget的进程发送了一个信号,signal:9,经过查找后在linux进程通信中发现9号信号就是强制结束进程的信号,可是为什么总是向widget进程发送这个信号呢,后来想起来AppWidgetProvider是BroadCastReceiver继承过来的,而BroadCastReceiver的说明里有这么一段话:

BroadcastReceiver如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成 . 这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束

BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的

所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的 。

关键原因在于widget所在进程属于没有活动组件的空进程,所以被杀,要想不被杀,是他拥有一个活动组件就行,比如service,虽然这样还会被杀死,但是比起之前2、3个小时就被杀掉一次的频率就小多了。而且可以提高service优先级。

综上所述要想而是用线程发送广播的方法来更新widget的同时要注意不能使得widget所在的进程成为空进程。不然非常容易被系统清理掉。

更多相关文章

  1. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  2. MIPI-DSI转HDMI
  3. Android开发规范之编码规范
  4. 2018-6月Android试题整理
  5. Android(安卓)Configuration change引发的问题及解决方法
  6. Android(安卓)使用 Usb Accessory 模式与 linux 下位机进行通信
  7. 【Android】编程规范与常用技巧
  8. 【腾讯开源】Android性能测试工具APT使用指南
  9. Android线程的一些问题

随机推荐

  1. Android学习路线总结,干货不多说
  2. Android逆向之旅---带你爆破一款应用的签
  3. android获取设备分辨率的新方法
  4. android中不小心使用静态变量会导致内存
  5. 【Android(安卓)Training - Performance
  6. Android(安卓)自定义View--从源码理解Vie
  7. [Android]分析 Sax解析Rss xml文件时,遇
  8. Android之Http通信——5.开发中遇到的一
  9. 学习笔记(一)Android(安卓)的简介
  10. 实现点击Item可让Item跳到屏幕中间的Hori