Download模块 (十二)

LocalDownloadResourceProvider implements了 DownloadPageProvider.
并且还封装了几乎所有create的view的逻辑交互<C>.
LocalDownloadResourceProvider还定义了几个要显示的View类。
LocalDownloadResourceProvider把V部分也给承包了。

<1> 定义了一个sectionContainerView,用于显示一批都是某个类型的itemView。
本质是一个vertical的LinearLayout,最上面的View作为一个title和折叠开关,其他view通过LinearLayout本身的
排布实现类似于列表的效果。

没有用ListView的原因是 考虑到这样的应用场景,可能会有很多个section, 每个section对应一个Lisview,想想麻烦,并且
涉及到点击section实现折叠展开也麻烦,adapter也会一堆。
LinearLayout在实现上比较简单,就按照这种方式来实现了。
一个section会包括两个部分,一直显示,并且在最上的section title,点击可以折叠/展开 section的内容,
然后就是一个真正容纳显示了DownloadItemView的contentView,可以被折叠/展开<用一个contentView包裹住所有的ItemView,
这样只改变contentView的visiblity就可以改变所有ItemView的visiblity>。

<2> sectionContainerView在构造初始化的时候就会从持久化的信息中将之前的Download信息全部载入,并按照此来更新UI上的内容<add
ItemView>,不过在调试中发现,一次性的add太多的itemView会引起进入DownloadFragment的卡顿,因此就实现为分批add,
每次add一定量的ItemView, add完这一批以后,post一个add下一批的runnable到主线程的下一个slice<因为UI操作只能在主线程>,直到全部add完.

<3> sectionContainerView维护了在此section的所有Download的信息<M>的引用, 以及对其内部View的引用<V>,同时还会保存一些状态信息<inEditMode, allSelected>这些状态数据应该是为C的部分.

<4> sectionContainerView 定义了一些abstract方法,让子类自己选择实现
getTitleLabel: section 的 title,
preloadContentsToPendingQueue: 如何将持久化的Download信息导入到sectionContainerView 的 pedingDownload list中去。
这一个函数的关键在于,每个section可能会展示符合某种条件的Download,因此这个步骤必须是可以由子类决定的,反正必须有可自由发挥的
地方。
getContentView: 获取contentView, 这一步也关键,因为每个section的contentView也是不同的,因此也要多态化。

<5> sectionContainerView 还实现了 onClickListener<C>,将自己内部View的click处理逻辑也都承包了,封装在自己的范围内。

<6> 折叠/展开的实现很简单,将contentView的visiblity改变,以及调整titleView的某些view.

<7> sectionContainerView同样对selectAll/clearAll等需要操作Itemview的方法 采用了 转发,单纯的调用 contentView的相关方法,
这也是一个基本的思想, 对于一个跨越了很多层的调用,每一层 都只专心于自己相关的事情,然后向下一层转发,直到处理完.

<8> DownloadingSectionView extends SectionView, 顾名思义,这个section展示的都是正在下载/暂停的Download,这时候
abstract的preloadContentsToPendingQueue起到了灵活性作用,自己定义了一套从所有Download过滤的机制,得到自己需要的Download,
而title也完全由该类自己决定。
getContentView生成自己定制的contentView.
该类监听了editMode change event。 那么在onAttach/DetachTo/FromWindow时应该register/unregister 监听器.
<这也是一个基本规范,对于View/Fragment,在 attach/dettach时要注意 监听器的注册和释放>

<9> DownloadedSectionView同上,只是显示的是已经下载完的DownLoad, 生成的contentView也是自己定制的。

<10> 上面取得所有当前Download信息的途径是通过DownloadManager<M>提供的接口 <数据流向: M->C->V>。

<11> SectionContentView是一个extends LinearLayout的class, 用于容纳itemsView,并作为sectionView的content呈现。
内部会维护一个存储了在其内部的ItemView的 LongSparseArray<SectionContentItemView><用long的原因是 key 是long的>,
每个itemView都和Download的Id一一对应,不需要再维护一个专门的Download list.

<12> SectionContentView也会在Edit/Normal之间进行切换,而同时SectionContentView还应该监听并处理一个
Download完成的事件<因为设计中会有两个SectionContentView容纳正在进行和和完成的download,这就需要在一个Download完成时,
按照自己的角色定位 加入/去掉 该download>,这一部分逻辑还要考虑到Edit模式的因素,如果是在Edit模式下,那么暂且不理会这个
Event,pending起来,等回到了normal模式再进行处理pending的event。而SectionContentView会对外开放一个自己内部的ItemView变化
event的监听借口<这个纯粹是交互上的考虑,一个SectionContentView中没有itemView的时候,应该自动折叠起来,这个event被设计的
更为通用,监视itemView的变化,而不是监视是否有itemView>,尽管可以通过给child获得SectionContentView内部的ItemView,
但是出于方便以及可以根据id直接获取对应的itemView,内部维护了一个longSparseArray来保存itemView。
也会有一个ArrayList来保存pending的Download。

<13> 增加一个Download到SectionContentView,可以在输入参数中指定添加在那个位置<index>,
动态生成一个ItemView<一个性能优化是可以将ItemView池化,牺牲内存提升速度,不过当时没做>,然后将Download 通过setter给
ItemView,在两者间建立映射<再次体现了M 和 V的分离>,如果没有指定index,那么获取一个合适的。这一部分的默认实现是
排在最下方<不过这个方法是一个protected的方法,可以子类自己定制>,然后常规的addView加入到contentView中,同时将id和itemView
填入到longSparseArray,最后如果有外部的itemviewNumChangeListener,那么触发。

<14>Remove Download更为简单<不过注意这个只是删除掉了View,即在V这一层删掉download的体现,但是在M中还保留>,通过Id获取了
Itemview,removeView,然后从相应的SparseArray同步清掉,而如果是在Edit模式下清除的,
还会触发一个表示此SectionContentView选中的item的数量变化的event<删除掉的itemview自然不可能是seletcted的了,细节>,
从pendingCompelete中也要清除此Download,这些都是V所维护的信息,而对DownloadManager维护的M信息,不进行操作。
其实可以给这个函数加一个标记输入 来标示 是否也删除M的信息。
这个函数是必须,因为V 和 M不能是绑定的, 在V上消失 不代表 在M中也应该被消除, 可能从这个V消失, 在另一个V显示。

<15>clear All基本同样操作,不过会把DownloadManager<M>中也清掉,

<16>select All 转发了方法select到每个ItemView中.

<17>clearAllSelected,内部调用了Remove和DownloadManager来实现V 和 M的同时移除,一个注意是
因为是需要遍历检测并处理ItemView的SparseArray,但是Remove本身会对SparseArray造成影响,因此需要
clone一个sparseArray来进行遍历<这和C++ STL中的erase以后iterator无效是一个case>

<18>规范做法,在View attach/deattach的时候 要register/unregister相应的Listener。

<19>上面只所以定义了一个contentView的abstract base class,是因为设计中的contentView会有不同的定位,
一个只会显示正在下载的,一个只会显示下载完成的。这个两个类主要的区别就在这里,开放出有变化和分歧的地方,
就是对下载完成的Download的处理不同,一个会remove view, 一个 会 add view。
不过除此之外,两者还要监听不同的事件,这一部分不同无法在base class中以函数表现出来<如果监听的事件一致的话,还是可以的,
当前两个子类已经有重复code了>

<20>DownloadedContentView override 了添加新View要显示位置的取得函数,根据完成时间来排序。

<21>Itemview也在该类中被extends了,主要实现其抽象的UpdateViewByStatus,以及对一系列的event的响应,
一个交互细节是会监听PackageChangeEvent,如果该event的packageName和Download一致,并且此ItemView代表的Download也已经完成,
那么根据event来携带的信息更新 itemview上button显示是打开 还是 安装。

<22>DownloadItemView切换Edit模式,对于有些按钮在两种不同模式下的还有不同selected显示图案的case,可以采用selector的方式实现.

<23>ItemView封装了自己的所有处理逻辑,所有的event到来的时候,都会统一的触发ItemView的update, 根据当前Download状态的不同,
采取不同的操作,当然在监听事件处理前,要对比一下event是否是针对自己所代表的Download,通过直接对比Download对像的地址<被id更
保险和方便>,注意ItemView在这里只是 随着 M的改动 来调整 V层面的变化。 Itemview应该尽量不改变M<除了在其实现的onCLickListener 等 C 中>,在DownloadW完成时,如果是COMPLETE,会execute一个AysncTask来从APK中获取Icon<IO活动>并在其onPostExecute中为ItemView设置上<这里有一个trick,就是 在设置前要检查此itemView是否还有相关的view组件,以及是否还为一个Download所服务,一个Android
guide 提倡的优化是 AysnTask应该维护的ItemView的一个weakReference,这样不会影响Itemview在不被使用时的GC,在这里,AsyncTask直接作为一个匿名内部类,必然会维护一个对ItemView的strongRef,而如果还实现了ItemView的池化重用,那么在onPostExecute的时候还要
检测当前的itemView所服务的Download是否还是AsynTask为之工作的Download>。

<24>对于View本身的click也会根据当前Download的状态引起不同的操作 <V -> M -> C>,long click也是如此,专门将Edit模式下,click的
处理抽离为一个单独函数。

<25>因为很多逻辑都封装了内部定义的各种view中,downloadProvider本身的逻辑不多,主要处理逻辑是自定义View之外的但是还在在layout
中的View组件的click等交互和。因为DownloadedSectionView和DownloadingSectionView本身在Provider这一层上还要区分出来以执行不同的逻辑<这其实某种意义上将已经破坏了封闭性,增加了耦合>,因此会有两个引用各指向不同的sectionView,
这样后面实现的clearAllSelected和getSelectedNum也直接在这两个引用上进行操作了,而更好的是因为两个sectionView都是同一个base
class,应该维护一个base class数组,然后上面这两个函数的实现直接遍历数组即可。

<26>按照项目的设计惯例,provider除了负责提供PagerView外,还应该提供对应的IndicatorView 和 title,总之一切自己的都由自己提供和管理。

<27>DownloadItemView都是基于相同的layout文件动态生成的,那么为了在Touch某个ItemView时能够正确的响应这个onClick,必须由ItemView实现onClickListener并

设置给自己,从外部不可能,而外部声明一个onClickListner则无法知道是哪个ItemView响应,因此只能由这种方式实现,这也是对于动态生成的相同layout的View做onClick判断的一种常用方法。

Download模块 (十二)相关推荐

  1. Linux攻关之基础模块十二 进程相关

    Linux系统进程管理 什么是进程 进程生命周期 监控和管理进程 静态监控进程 动态监控进程 信号管理进程 后台进程管理 1.什么是进程 进程是已启动的可执行程序的运行实例,进程有以下组成部分分配内存 ...

  2. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十二:串口模块① — 发送

    实验十二:串口模块① - 发送 串口固然是典型的实验,想必许多同学已经作烂,不过笔者还要循例介绍一下.我们知道串口有发送与接收之分,实验十二的实验目的就是实现串口发送,然而不同的是 ... 笔者会用另 ...

  3. Python入门(二十二)- 常见模块2(正则表达式及容器)

    二十二 常见模块2(正则表达式及容器) 22.1 正则表达式及re模块 正则表达式(Regular Expression)用于描述一种字符串匹配模式(Pattern),它可以用于检查一个字符串是否含有 ...

  4. BetaFlight模块设计之三十二:MSP协议模块分析

    BetaFlight模块设计之三十二:MSP协议模块分析 1. MSP协议模块 1.1 MSP描述 1.2 MSP版本优缺点 1.3 MSP代码资源 2. MSP报文解析 2.1 MSP收包状态机 2 ...

  5. BetaFlight模块设计之十二:电传任务分析

    BetaFlight模块设计之十二:电传任务分析 电传任务 taskTelemetry任务分析 subTaskTelemetryPollSensors函数分析 telemetryProcess函数分析 ...

  6. 第二十二章 核心与核心模块

    谈完了整个启动的流程,您应该会知道,在整个启动的过程当中, 是否能够成功的驱动我们主机的硬件配备, 是核心 (kernel) 的工作! 而核心一般都是压缩档,因此在使用核心之前,就得要将他解压缩后, ...

  7. Simulink代码生成(二十二)——TSP开发之创建外部设备模块

    Simulink代码生成(二十二)--TSP开发之创建外部设备模块 文章目录 Simulink代码生成(二十二)--TSP开发之创建外部设备模块 一.C Mex Sfunction文件解读 一.C M ...

  8. Slicer学习笔记(六十二)slicer下导出模块接口

    Slicer学习笔记(六十二)slicer下导出模块接口 1. 参考文件实现 1. 参考文件实现 通过配置config_file为每一个生成类添加 Export,并为每个Module生成 Export ...

  9. 模块开发之React使用第三方库PropTypes属性限制(十二)

    模块开发之React使用第三方库PropTypes属性限制(十二) 前言 这是一个纯配置的第三方库模块,所以我们需要掌握知识不需要太详细.能知道并拿来即用即可. 下面以使用该模块的背景展开,然后介绍使 ...

最新文章

  1. 4 用python进行OpenCV实战之图像变换1(平移)
  2. 「杂谈」AI工业界都有哪些值得参加的比赛?
  3. JavaScript的键盘事件
  4. 交换机接口的access与trunk
  5. 【干货】史上最全的Tensorflow学习资源汇总
  6. 一个Java对象到底占多大内存?(转)
  7. react组件之间重用状态
  8. C# 使用 Windows API 操作控件: SendMessage
  9. 剧透人生!你什么时候结婚换工作甚至狗带,Facebook都知道
  10. [渝粤教育] 西南科技大学 单片机原理与应用 在线考试复习资料(2)
  11. C++多态讲解以及常见面试题
  12. 安装php扩展phpredis
  13. keras中的EarlyStopping
  14. dpdk对虚拟化的支持
  15. ajax验证作用,通过正则表达式使用ajax检验注册信息功能
  16. IEC60870-5-103规约通讯过程
  17. python caffe框架_caffe框架基础
  18. 用java实现九九乘法表的打印
  19. 老路《用得上的商学课》学习笔记(1-5课)
  20. 数组添加/扩容和数组缩减

热门文章

  1. 2023年高考成绩发布后会统一排名吗
  2. 操作系统开发--Hello OS-开始操作系统开发
  3. Zookeeper笔记(二)Paxos算法与Zookeeper的工作原理
  4. 菜鸟学源码之Nacos v1.1.3源码学习-Client模块(2):NacosConfigService
  5. 关于clock.avi文件
  6. 北京科技大学和北京交通大学考研计算机,2021北京交通大学计算机专硕考研经验分享...
  7. 如何自建微信外卖平台_怎么在微信上做外卖?
  8. 千兆网络变压器和百兆网络变压器有什么区别?不能互换使用吗?
  9. 微信客户端开启vconsole调试
  10. 深入理解操作系统(16)第六章:存储器层次结构(2)高速缓存存储器+对程序性能的影响(包括:L1/L2高速缓存历史/缓存写:直写和写回/暂无L4级缓存/缓存命中率/存储器山/高速缓存友好的代码/)