资讯专栏INFORMATION COLUMN

Android UI:机智的远程动态更新策略

nifhlheimr / 358人阅读

摘要:对于元素,即上图的列表项不是元素,并没有实现远程更新的策略。故实际项目中,只对内容作了远程控制动态更新机制的处理。目前腾讯内部所有的产品,均在使用其进行线上产品的崩溃监控。

腾讯Bugly特约作者: 王金波

问题描述

做过Android开发的人都遇到过这样的问题:随着需求的变化,某些入口界面通常会出现 UI的增加、减少、内容变化、以及跳转界面发生变化等问题。每次发生变化都要手动修改代码,而入口界面通常具有未读信息提醒这样的“小红点”逻辑;一旦UI变化,“小红点”逻辑也要重新计算。如果不同的RD来维护这些代码,耦合性非常高,出错概率也很大。本文以自选股的个人页卡为例(界面如下图所示),并给出了一套方案来解决动态更新UI的问题以及更好的解决未读提醒的逻辑。


旧的方案(Phase out)

(1)对于UI动态变化的问题,通常结合远程控制来解决。以上图的“资产管理”为例,旧的解决方案会在XML写死全部的item,如:“港股交易”、“基金交易”和“精品理财”这三个item。然后根据后台传递过来的json解析出需要隐藏哪些item。点击不同的item会跳转到不同的activity(如下图所示),这部分跳转操作也是写死在代码中的。

这解决了一部分问题,但是如果需求新增了item,比如新增了“沪深交易”、“美股交易”,那就需要改动现有代码了。

(2)对于未读指示(小红点)功能,它的作用是,有未读信息来了,需要在UI上面显示一个小红点提醒用户。比如下图的,股友动态的头像提醒,资产管理的“NEW”提醒,系统设置的新版本提醒等。

旧的方案是定义了一个int型(32位),用它的每一位代表一个UI上的Item。比如好友动态是第1位,未读提醒是第2位... 小红点思想是哪个item有未读信息,则该int型对应的那一位就置1,否则为0。一旦某个item有未读提醒的改变,则将这个int型对应的位改变,异步写入SharedPreference中,同时利用观察者模式通知UI做更新,如下图所示:

上述做法总体来说最大的缺陷就是没有做到“开放-封闭”原则。面对扩展的时候,即添加一个item则不得不修改现有代码,需要在该int型中添加一位标志位,观察者模式也要注册新item。所以下面我会介绍另一种方案可以更好的解决该问题。


新的解决方法

(1) 数据抽象

首先进行数据的抽象,并将UI进行分组,如下图所示:

按照组合模式,将数据以树形结构组织起来,表现“整体/部分”层次结构,如下图所示。这样做的好处是,可以以一致的方式来处理个别对象以及对象组合。蓝色的表示节点,而绿色的表示叶节点。

组合模式的类图,如下所示:

对UI进行的数据抽象。无论是ListItem列表项,还是GridView Item的项,都采用了PersonalItem对象来表示,如下所示:

对于PersonalItem来说,有些没有意义的方法(如add()、remove()、getChild())就不实现,调用它们会抛出UnsupportedOperationException()异常。

(2) 完美解决未读提醒(小红点)的问题

关于计算小红点,PersonalGroup类利用组合+迭代器的模式,代码如下:

这里使用了迭代器,用它遍历所有PersonalComponent组件。遍历过程中可能遇到PersonalItem也可能遇到PersonalGroup。由于它们都是PersonalComponent,且实现了getUnreadIndicator()方法,那我们只需调用getUnreadIndicator()即可。

如上图所示,PersonalGroup中加载的是PersonalComponent,可能是PersonalItem也可能是PersonalGroup。组合模式的优点就是无视具体类型 -- 获取出来的都是PersonalComponent,然后利用多态,调用具体类的getUnredIndicatorCount()方法。如果是PersonalGroup,则继续调用它的这个方法(与此方法一样,会开始另一个遍历);如果为PersonalItem,则说明遍历到了树形结构的末端(即叶节点),则进行如下处理:

如果getUnreadIndicator为true,则表示该PersonalComponent需要显示小红点。因此,利用上述组合+迭代方式,运用递归在根节点处进行一次调用即可。如下图所示,当计算出叶节点“A股大赛”有未读提醒,则它上级的groups也有未读提醒,一直统计到根节点。

getUnredIndicatorCount()是每一个item自己来决定自己是否需要展示小红点的方法。这就是将局部与整体解耦了。整体上面,需要计算小红点,至于如何计算则委托给具体类来实现。即面向对象中的将 "做什么" 与 "怎么做"分开。RD可以从中解放出来,不必关注整体实现,只需关注自己的实现即可。比如,需要在“资产管理”中添加“美股交易”,RD只需添加“美股交易”的内容即可。下一节会说明,这部分内容也由远程控制来代劳了,远程控制传递过来的Date与本地存储的Date比较,如果是新的Date值,则证明这个Item为“NEW”,则对应的小红点需要显示。

(3)远程控制动态更新UI

当远程控制发生变化时(5分钟主动发一次请求),通过解析远程控制接口返回的json串,生成PersonalItem对象的列表。其中每一项对应UI上面的一个Item。需要注意的是,这里还包含了一个URL,它是点击UI控件跳转的URL。以“资产管理”为例,它包含“沪深交易”、“基金交易”等子项。当点击任意一个子项的时候启动的是同一个Activity - WebviewActivity,它包含一个WebView控件。因为每个子项的跳转URL不一样,所以这个WebView load了不同的URL,即完成了跳转不同界面的问题。 然后按照上面描述的树形结构,把PersonalItem放到Groups中。如下图所示:

Model存储了待显示的数据结构。这份数据通过Parser的解析生成UI的内容。过程如下图所示:

Parser模块是一个递归函数,递归的对Model进行解析。并将解析出来的List Item、Grid Group、GridView Item加载各自的XML文件,在程序中动态的添加UI组件。其中onClick事件是在定义PersonalItem的时候已经写好了回调。例如,“资产管理”属于Grid Group,其子项“沪深交易”、“基金交易”等属于GridView Item。在上述“Build PersonalItem Objects”步骤中,已经定义了onClick方法,调用onClick方法跳转至WebViewActivity,这个Activity会加载不同GridView Item的URL,从而实现点击不同item跳转不同页面的目的。

Note:

对于ListItem元素,即上图的列表项(不是GridView元素),并没有实现远程更新的策略。因为它们跳转的逻辑是跳转到各自的Activity,是固定不变的;并且它们的文字描述、图标、是否隐藏均不需要后台来控制更新。故实际项目中,只对GridView内容作了远程控制动态更新UI机制的处理。

另外,在通过远程控制动态更新UI的过程中也遇到了一些坑,比如远程控制更新的时刻,恰好用户退出app,此时系统刚好销毁activity。那么在执行到上述Parser模块的inflateUI的时候就需要判断当前上下文是否为空,如果为空则直接退出。


结论与数据

本文通过将UI数据进行抽象,利用组合模式进行数据的构建。利用递归的方式将数据映射为UI。同时处理了点击事件。数据源则可以通过远程控制动态的更新,RD从中解放。另外,组合+迭代器的方式完美的解决了小红点的问题,遵循了“开放-封闭”原则,将“做什么”与“怎么做”分开。下图从数据的角度描述了改版前后 代码量、Bug量 以及 RD工作量的差异。


腾讯Bugly简介

Bugly是腾讯内部产品质量监控平台的外发版本,其主要功能是App发布以后,对用户侧发生的Crash以及卡顿现象进行监控并上报,让开发同学可以第一时间了解到App的质量情况,及时机型修改。目前腾讯内部所有的产品,均在使用其进行线上产品的崩溃监控。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/12427.html

相关文章

  • 基于ShineBlink物联网开发板和机智云平台开发“针对短期内宠物无人照顾智能宠物屋”系统

    摘要:为了解决人们因工作出差旅游等短期时间内家中宠物无人照顾的问题,我们基于物联网开发板机智云平台和各类传感器模块研究设计了一套针对短期内宠物无人照顾的智能宠物屋系统。 正式介绍作品前先说明一下,我是湖南文理学院计算机与电气工程学院的一名大三学生,我叫陈海涛。作品全部内容均为个人创意、个人设计并手...

    jerryloveemily 评论0 收藏0
  • 深入了解 Messenger 实现细节

    摘要:简单的了解了的基本使用后,下面我们就来看看的源代码,了解一些内部的实现细节。当需要服务进程回调客户端进程时,则需要传入了。按照系统一向的风格,都是偏向于推荐继承来实现。实际上是的一个私有内部类,它继承了并实现方法。 近一个半月因为工作变动的缘故,忙着交接工作和复习面试。没有多少时间来写博客,连一周三次的健身都有几个星期没练了,好多同事问我是胖了还是壮了(我迅速就岔开话题了,机智boy)...

    bingo 评论0 收藏0
  • 【网易云信】H5 容器技术方案

    摘要:开发原生应用是手机操作系统厂商目前主要是苹果的和的对外界提供的标准化的开发模式,他们对于开发提供了一套标准化实现和优化方案。同时增加对模版的校验,防止资源的篡改。与的请求委托,将鉴权信息等部分接口委托至端,增加安全性。 Native 开发原生应用是手机操作系统厂商(目前主要是苹果的 iOS 和 Google 的 Android)对外界提供的标准化的开发模式,他们对于 Native 开发...

    longshengwang 评论0 收藏0
  • 有用框架级东西

    摘要:多个可以提高你安卓开发技能的开源学习的最佳方式就是阅读,对程序员来说也是如此。如何做一个崩溃率少于千分之三噶应用章节列表这个系列的有关架构的概念,适合有大概三年以上经验的同学理解。 Android 开源图表库 - SmallChart SmallChart 是一个开源的 Android 图表库,拥有 5 种不同的图表类型来展示数据。可以通过输入的数据以及可设置的颜色、画笔大小等属性方便...

    MadPecker 评论0 收藏0
  • 【腾讯bugly干货】关于 Android N 那些你不知道事儿

    今年3月,Google 破天荒提前半年发布了 Android N 开发者预览版。当然,作为一个不合格的谷粉并没有第一时间体验安装,因为至今仍然能够回忆起来去年今日此门中(雾)兴冲冲刷了 Android M Preview 的时候发现各种 Crash 就连微信也(不出所料得)中招时自己一脸懵逼的心情。当然,为自己的机智而庆幸并没有过多久,很快就有微信好友(当然也是纯纯的谷粉)反馈微信又双叒叕在 An...

    zombieda 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<