android异步更新ui 头像修改后别的ui头像怎么更新

iOS实战(1)
下面是我写的两个页面:
我的页面:
我的页面获取个人资料代码:
- (void)viewDidLoad {
[super viewDidLoad];
[self getUserInfoData];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getUserInfoData) name:@"UserInfoChangeSuccess" object:nil];
- (void)getUserInfoData {
[[SDImageCache sharedImageCache] clearDisk];
NSString *urlString = @"";
NSString *urlStr = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[HttpHelper requestMethod:@"GET" urlStr:urlStr token:value parma:nil success:^(id json) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([json[@"data"][@"userInfo"] objectForKey:@"portrait"]) {
NSString *portrait = json[@"data"][@"userInfo"][@"portrait"];
[defaults setObject:portrait forKey:@"portrait"];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://123.56.77.171/app%@", portrait]];
[_centerView.headImageView sd_setImageWithURL:url placeholderImage:nil options:SDWebImageRefreshCached];
[defaults synchronize];
} failure:^(NSError *error) {
修改个人资料页面:
修改头像并将头像URL存储到本地:
- (void)uploadHeadImage {
NSString *urlString =@"";
NSString *urlStr = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[HttpHelper uploadFileWithMethod:@"PUT" URL:urlStr token:value name:@"image" fileName:@"image.jpg" param:nil image:_dataView.headPhotoImage.image success:^(id json) {
if (json) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *portrait = [NSString stringWithFormat:@"http://123.56.77.171/app%@", json[@"data"]];
[defaults setObject:portrait forKey:@"portrait"];
[defaults synchronize];
[weakself.navigationController popViewControllerAnimated:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:@"UserInfoChangeSuccess" object:nil];
} failure:^(NSError *error) {
} progress:^(long long totalBytesWritten, long long totalBytesExpectedToWrite) {
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6623次
排名:千里之外
原创:46篇
转载:31篇
(1)(46)(5)(4)(10)(12)查看: 497|回复: 4
Android UI:机智的远程动态更新策略
该用户从未签到主题帖子e币
特约作者:王金波
一、问题描述做过的人都遇到过这样的问题:随着需求的变化,某些入口界面通常会出现 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跳转不同页面的目的。
对于ListItem元素,即上图的列表项(不是GridView元素),并没有实现远程更新的策略。因为它们跳转的逻辑是跳转到各自的Activity,是固定不变的;并且它们的文字描述、图标、是否隐藏均不需要后台来控制更新。故实际项目中,只对GridView内容作了远程控制动态更新UI机制的处理。
另外,在通过远程控制动态更新UI的过程中也遇到了一些坑,比如远程控制更新的时刻,恰好用户退出app,此时系统刚好销毁activity。那么在执行到上述Parser模块的inflateUI的时候就需要判断当前上下文是否为空,如果为空则直接退出。
四、数据与结论本文通过将UI数据进行抽象,利用组合模式进行数据的构建。利用递归的方式将数据映射为UI。同时处理了点击事件。数据源则可以通过远程控制动态的更新,RD从中解放。另外,组合+迭代器的方式完美的解决了小红点的问题,遵循了“开放-封闭”原则,将“做什么”与“怎么做”分开。下图从数据的角度描述了改版前后 代码量、Bug量 以及 RD工作量的差异。
Bugly是腾讯内部产品质量监控平台的外发版本,其主要功能是App发布以后,对用户侧发生的crash以及卡顿现象进行监控并上报,让开发同学可以第一时间了解到app的质量情况,及时机型修改。目前腾讯内部所有的产品,均在使用其进行线上产品的崩溃监控。
本帖子中包含更多资源
才可以下载或查看,没有帐号?
签到天数: 108 天连续签到: 2 天[LV.6]常住居民II主题帖子e币
学习了,多谢楼主分享
签到天数: 2 天连续签到: 1 天[LV.1]初来乍到主题帖子e币
代码重构,牛X!!!!!
签到天数: 48 天连续签到: 1 天[LV.5]常住居民I主题帖子e币
学习了。。。。。。。。。。。。。。。。。。
该用户从未签到主题帖子e币
本帖最后由 bugly 于
13:58 编辑
腾讯自选股开发同学出品,哈哈哈
推荐阅读热门话题
61882417416379326279278260256251226218210206715
半小时前1&小时前2&小时前3&小时前4&小时前6&小时前7&小时前7&小时前7&小时前8&小时前8&小时前9&小时前昨天&23:54昨天&22:48昨天&20:51昨天&19:06
Powered by

我要回帖

更多关于 android广播更新ui 的文章

 

随机推荐