Launcher AppWidget小部件更新过程

1. 系统开机后向AppWidgetProvider发送OnEnable, onUpdate的广播流程说明
1)AppWidgetService是运行在system_server进程, 当收到user解锁回调后,会遍历该user下的appWidget.xml文件,获取到已经在Launcher上布局的AppWidgetProvider及其下所有的Widget, Widget信息里包含AppWidgetId值。
2)然后给每个Provider发送一条onEnable广播,及onUpdate广播带有该Provider下所有AppWidgetIds信息。 最后调用到Provider里的onEnable()及onUpate()中。
3)当AppWidgetProvider收到onEnable或onUpdate时,通过AppWidgetManager接口向Launcher更新RemoteViews,开机后此时Launcher才第一次获得到要更新的对应AppWidgetHostView的消息,进行更新。
关键代码:
在这里插入图片描述
2. AppWidgetProvider向Launcher更新RemoteViews的执行流程
特别说明在调用到Launcher端AppWidgetHostView类中时, Launcher端更新过程:
1) 在updateAppWidget中调用applyRemoteViews, 并且第二个异步参数传入true, Android原生framework代码逻辑。
在这里插入图片描述
2)2)在applyRemoteViews中,运行在Launcher主线程中,
会执行mLastExecutionSignal.cancel(); 该函数会对异步的RemoteViews的action映射过程进行取消。取消上一次更新的AsyncTask执行。
在这里插入图片描述
3)因为采用异步方式,所以执行inflateAsync进行本次更新。
4)在此处重新赋值本次的mLastExecutionSignal对象,如果下一次更新时, 还会调用本次的cancel来取消异步task执行。
在这里插入图片描述
5)分析下RemoteViews里异步的执行过程:

  • 在startTaskOnExecutor()中设置了cancellistener。
    即当上一步调用mLastExecutionSignal.cancel()时,
    onCancel()函数被执行。
    在这里插入图片描述

  • 在doInbackground执行映射每个action时, 如果判断已cancel则不再执行for循环。并且onPostExecute不会被执行。

    onPostExecute的执行是在Launcher主线程, 执行中会调用AppWidgetHostView的onViewApplied() 更新view。
    在这里插入图片描述

以上过程想说明,如果在AysncTask异步执行过程中,Post到主线程执行前,如果被cancel了,那么Launcher上Widget的view显示是不会被更新的。因此,如果AppWidgetProvider端高频率的短时间间隔调用updateAppWidget, 可能出现Launcher还未来得及加载view时,已经被下一次更新cancel掉了。这样会缺失上一次的更新view, 从而导致AppWidgetHostView中显示的remoteview与期望更新上的不同步。

以上过程都是基于AOSP O版本以后的流程,采用了异步更新方式。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值