Android AppWidget实践

前面

业务工作需要,需要为App增加AppWidget功能,做到不打开App也能完成部分功能使用

一般情况下,按照官网或其它技术文章都可以得到相关的使用

这里将实践过程中的一些知识点记录

关于AppWidgetProvider

它是一个AppWIdget的最重要的元素,就像页面与Activity之间的关系,

观察它的父类,它就是一个BroadcastReceiver,通过接收广播来触发内部多个方法的回调,比如onUpdate、onDelete等

App内部有更新需求的时候,其中一种就是通过发送Intent来触发AppWidgetProvider的onUpdate方法 (另外一种是直接通过Manager.update(remoteview))

有的App提供多种AppWidget,来说京东App就提供了4种,在实现方式上就需要提供4个AppWidgetProvider 

每种AppWidget都有一个名字,可以通过AndroidManifest.receiver标签下的label来指定

每种AppWIdget,在桌面上可以重复添加,体现在代码上的影响就是多个WidgetId

 

关于RemoteView

观察它的父类,没有继承至View,所以不能认为它是一个View

它只是一个对View的描述,也可以对View进行操作,而最终View是在其他进程上显示的

对于它的操作,需要使用特定的方法,观察其内部方法的调用,每个动作都涉及到序列化和反射

对于没有提供的方法,可以直接通过告知方法名和参数的方法

remoteViews.setFloat(R.id.controlLayout, "setWeightSum", weightSum)

 

关于PendingIntent

AppWidget的View上的元素,肯定会存在点击事件,其事件都需要包装成PendingIntent 

PendingIntent和RemoteView 他两很搭配

这里的注意点是,构建PendingIntent的时候,提供的RequestCode最好是具备唯一性的,不然他会被后面添加的事件覆盖。

 

整体实现的一些设计

AppWidget上的点击事件,做包装成指令/命令之后,发送给一个新的BroadcastReceiver,由这个新的Broadcast对其进行业务处理

处理过程中,或处理结束之后,需要将结果体现在AppWidget上,这个时候就再次发送action: AppWidgetManager.ACTION_APPWIDGET_UPDATE (携带一些构建View需要的参数) 给 KeyAppWidgetProvider 触发它的onUpdate方法

举例一个业务:

点击一个按钮,按钮点击之后需要转圈圈,后台还会发送网络请求,请求响应结束之后,转圈圈关闭,展示Toast(执行成功)

代码实现上是,按钮点击的时候,上文提供的新的BroadcastReceiver接收到指令,进行处理

1. 向KeyAppWidgetProvider发送一个更新指令,其内部包含的参数告知他 需要让某个View上展示转圈圈

2. 网络请求调用

3. 得到网络请求的响应之后,向KeyAppWidgetProvider发送一个更新指令,其内部包含的参数告知他 需要让转圈圈结束,展示toast

4. 1秒之后,向KeyAppWidgetProvider发送一个更新指令,其内部包含的参数告知他 隐藏toast

 

补充一个解决问题的思路

 项目中遇到的一个bug,期望构建的Widget是一个4x2的尺寸,但是在一台华为手机上的表现是3x2,属于适配上的问题,从参数配置上,已经完全按照官网教程添加的尺寸参数,但是出现这样的问题很懵逼

后来解决的办法是,从网络上下载其他具有相同尺寸Widget的APK,再通过反编译,查看其中AppWidgetProvider的配置,进行对照的修改,最后成功解决这个问题

借助对竞品APK的反编译或其它手段的分析/学习,也是一个解决问题的很好办法

我日常常用的反编译工具是jadx-gui,很方便

 

最后

中间有看过一些开源项目/Demo,回顾本次对AppWidget的使用还是比较浅的,

比如RemoteViewsService都还没用到,看注释是服务于列表类的控件;

每次刷新都是整个的刷新,比较希望存在一种局部刷新的方法

 

 

RemoteViewsService
 
posted @ 2023-01-11 18:00  zhou_guobao  阅读(131)  评论(0编辑  收藏  举报