Download模块 (十六)
Notification类算是一个比较独立的模块以及一个工具性的C+V角色<负责主动或被动的显示更新Notification,没有它也能跑,封闭性
比较好>。
所有方法都是static的,类实际搞成一个static的都可以。或者单例模式。
构造函数直接private
Notification内部没有实现什么listener,设计的时候不想让Nofticiation主动感知Download,而是应该作为一个被动的工具被调用。
<1>为了对每个Download相关的Notification进行追踪和更新,需要维护一个SparseArray来保存当前还存在的Notification<V><这样可以通过
id快速定位Download所属的Notification>。
<2>直接一个static final的引用指向了该Context所属的NotificationManager<简化code,cache引用>
<3>一个staic final flag直接初始化就得到是否能够在Notification上显示更多信息<由屏幕宽度决定
context.getResources().getDisplayMetrics().widthPixels>
<4>因为和DownloadTask<M>打交道最多<有依赖>,因此很多函数的输入参数都是DownloadTask<其实有某种的耦合了,Notification某种意义
上是不需要知道DownloadTask的存在的,就像V 其实 不太需要知道 M>
<5>Notification没有public的,只有少数几个package access的<没有必要做成一个通用的模块>,其他都是private。
<6>在一个Download开始的时候,Notification的onDownloadStarted会被调用,处于鲁棒性,会检查是否已经创建了相应的Notification
如果没有,就create 一个,然后将此Notification和此Download<其实之需要一个id> 绑定起来。
<7>创建一个Notification是比较常规的流程,不过因为Notification使用了自定的view以及一些交互,因此需要使用RemoteView这个类,
并且结合PendingIntent才能实现与Service/Activity的交互。通过PendingIntent.getBroadcast来指定Intent和BroadcastReceiver打
教导,还有就是Notification的创建,现在已经变为了通过使用builder这种建造者模式来的到。不过如果版本<HC的话,contentView还需要
手动的赋值到RemoteView。
构造时,setOngoing(true)<不能被用户取消>,setPriority(Notification.PRIORITY_MAX)
在构建完Notification以后,就要根据Download的状态来更新Notification的显示<尤其是从持久化恢复出来的Download这种case>,
通过Notification的contentView可以获得RemoteView,然后就可以使用RemoteView提供的方法<很多,多参考API>来根据Download
状态调整RemoteView上某个View的状态。
<8>在调整好Notification,就可以将其展示出来了,因为将来还会对Notification进行更新,因此在NotificationManager的
notify函数中除了生成的Notification对象外,还需要一个序号/id<直接取Download的id>标示此Notification.
出于便利,Download的上一次的大小和上一次的下载速度都会被保存在两个sparseArray中。
<9>在任何Notification UI上关注的信息<progress/speed>变化时,Notification的update都会被调用,
同样的根据当前信息通过RemoteView更新完Notification以后,只有这一步不够,不能体现在UI上,还需要再次调用
NotificationManager的notify函数结合要更新的Notification的Id提交更新过的notification才能将改动显示在UI上。
<10>除了给RemoteView的某个View绑定一个PendingIntent外,在构建Notification的时候可以通过Builder的setContentIntent指定点击了
Notification其他没有别的PendingIntent的区域时触发的Intent。
<12>Notification的flags很重要,在创建或者更新Notification的时候,要按照Download的状态来更新flag。在
IN_PROGRESS/PAUSED时,要取消FLAG_AUTO_CANCEL,设置FLAG_ONGOING_EVENT,这样用户点击以后才不会消失,并且不能被取消。
而在FAIL/COMPLETE/FILE_BROKEN,则反之。
setOngoing就是设置了FLAG_ONGOING_EVENT这个flag。
<13>在Download的status发生变化的时候,Notification也应该被更新,获取了对应的Notification以后,如果当前status变化为了
IN_PROGRESS, 那么就调用onDownloadStarted来更新Notification为正在运行。
否则,如果已经完成,并且DownloadTask被remove掉了,那么Notification也不需要显示了,直接调用NotificationManager的cancel(id),
然后将此Notification的痕迹全部clear.
如果是COMPLETE/FAIL/FILE_BROKEN那么也需要更新都应的Notification,并将之推送到V上去。
<14>还提供了一些集体操作函数,取消所有的Notification<遍历调用每个的cancel>
Notification类算是一个比较独立的模块以及一个工具性的C+V角色<负责主动或被动的显示更新Notification,没有它也能跑,封闭性
比较好>。
所有方法都是static的,类实际搞成一个static的都可以。或者单例模式。
构造函数直接private
Notification内部没有实现什么listener,设计的时候不想让Nofticiation主动感知Download,而是应该作为一个被动的工具被调用。
<1>为了对每个Download相关的Notification进行追踪和更新,需要维护一个SparseArray来保存当前还存在的Notification<V><这样可以通过
id快速定位Download所属的Notification>。
<2>直接一个static final的引用指向了该Context所属的NotificationManager<简化code,cache引用>
<3>一个staic final flag直接初始化就得到是否能够在Notification上显示更多信息<由屏幕宽度决定
context.getResources().getDisplayMetrics().widthPixels>
<4>因为和DownloadTask<M>打交道最多<有依赖>,因此很多函数的输入参数都是DownloadTask<其实有某种的耦合了,Notification某种意义
上是不需要知道DownloadTask的存在的,就像V 其实 不太需要知道 M>
<5>Notification没有public的,只有少数几个package access的<没有必要做成一个通用的模块>,其他都是private。
<6>在一个Download开始的时候,Notification的onDownloadStarted会被调用,处于鲁棒性,会检查是否已经创建了相应的Notification
如果没有,就create 一个,然后将此Notification和此Download<其实之需要一个id> 绑定起来。
<7>创建一个Notification是比较常规的流程,不过因为Notification使用了自定的view以及一些交互,因此需要使用RemoteView这个类,
并且结合PendingIntent才能实现与Service/Activity的交互。通过PendingIntent.getBroadcast来指定Intent和BroadcastReceiver打
教导,还有就是Notification的创建,现在已经变为了通过使用builder这种建造者模式来的到。不过如果版本<HC的话,contentView还需要
手动的赋值到RemoteView。
构造时,setOngoing(true)<不能被用户取消>,setPriority(Notification.PRIORITY_MAX)
在构建完Notification以后,就要根据Download的状态来更新Notification的显示<尤其是从持久化恢复出来的Download这种case>,
通过Notification的contentView可以获得RemoteView,然后就可以使用RemoteView提供的方法<很多,多参考API>来根据Download
状态调整RemoteView上某个View的状态。
<8>在调整好Notification,就可以将其展示出来了,因为将来还会对Notification进行更新,因此在NotificationManager的
notify函数中除了生成的Notification对象外,还需要一个序号/id<直接取Download的id>标示此Notification.
出于便利,Download的上一次的大小和上一次的下载速度都会被保存在两个sparseArray中。
<9>在任何Notification UI上关注的信息<progress/speed>变化时,Notification的update都会被调用,
同样的根据当前信息通过RemoteView更新完Notification以后,只有这一步不够,不能体现在UI上,还需要再次调用
NotificationManager的notify函数结合要更新的Notification的Id提交更新过的notification才能将改动显示在UI上。
<10>除了给RemoteView的某个View绑定一个PendingIntent外,在构建Notification的时候可以通过Builder的setContentIntent指定点击了
Notification其他没有别的PendingIntent的区域时触发的Intent。
<11>在被触发要更新UI的时候,需要做一个检查,看一下当前UI上显示的参数是否真的发生了变化,没有变化就不需要更新Notification,
或者增加一个变化显示阈值.
<12>Notification的flags很重要,在创建或者更新Notification的时候,要按照Download的状态来更新flag。在
IN_PROGRESS/PAUSED时,要取消FLAG_AUTO_CANCEL,设置FLAG_ONGOING_EVENT,这样用户点击以后才不会消失,并且不能被取消。
而在FAIL/COMPLETE/FILE_BROKEN,则反之。
setOngoing就是设置了FLAG_ONGOING_EVENT这个flag。
<13>在Download的status发生变化的时候,Notification也应该被更新,获取了对应的Notification以后,如果当前status变化为了
IN_PROGRESS, 那么就调用onDownloadStarted来更新Notification为正在运行。
否则,如果已经完成,并且DownloadTask被remove掉了,那么Notification也不需要显示了,直接调用NotificationManager的cancel(id),
然后将此Notification的痕迹全部clear.
如果是COMPLETE/FAIL/FILE_BROKEN那么也需要更新都应的Notification,并将之推送到V上去。
<14>还提供了一些集体操作函数,取消所有的Notification<遍历调用每个的cancel>