android开发之widget控件突然停止更新的原因
android开发之widget控件突然停止更新的原因
微笑的江豚 发表于7个月前
android开发之widget控件突然停止更新的原因
  • 发表于 7个月前
  • 阅读 12
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

      在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所在的进程成为空进程。不然非常容易被系统清理掉。

共有 人打赏支持
微笑的江豚
粉丝 24
博文 445
码字总数 47615
作品 2
×
微笑的江豚
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: