Gallery 数据结构(仅包含数据怎么组织,不包括UI布局)
分析这个数据结构的目的是为把Videoset移到Albumset界面提供可行思路。
需求是把videoset放在albumset的第一个位置,有视频时显示,无视频时隐藏,在这个布局中videoset不支持长按选择。
- TimeLinePage
typeBits 是DataManager.INCLUDE_ALL
getTopSetPath 是 "/combo/{/local/all,/picasa/all}"
CLUSTER_BY_TIME 切换后:/cluster/{/combo/{/local/all,/picasa/all}}/time
path.getPrefix() 前缀 是combo
根据前缀,对应的mediasource是ComboSource。
在ComboSource中,path 是ombo/{/local/all,/picasa/all}
Segments[0] 是combo
Segments[1] 是{/local/all,/picasa/all}
mMatcher.match(path)=0,所以对应的mediaset是ComboAlbumSet。
Segments[1]里面实际包含了两个mediaset,一个path是/local/all,一个path是/picasa/all/
然后ComboAlbumSet构造函数中的最后这个参数:
dataManager.getMediaSetsFromString(segments[1])
会返回两个MediaSet,具体计算是在DataManager中方法getMediaSetsFromString,根据路径/local/all,/picasa/all/分别获取相应的MediaSet。
针对/local/all对应的MediaSet:
这个path的prefix是local,匹配的MediaSource是LocalSource,所以接着调用LocalSource的CreateMediaObject方法:
在LocalSource中,/local/all ,mMatcher.match(path) 值是6,即LOCAL_ALL_ALBUMSET。
所以返回的Mediaset就是LocalAlbumSet,也就是/local/all 这个path对应的Mediaset是LocalAlbumSet。
另外一个路径/picasa/all/对应的MediaSet,同样的计算方式:
/picasa/all/的prefix是picasa,由mSourceMap匹配的MediaSource是PicasaSource,所以会调用PicasaSource的CreateMediaObject方法获取对应的MediaSet,
结果是com.android.gallery3d.picasasource.PicasaSource$EmptyAlbumSet。
最终ComboAlbumset中包含了两部分,一个是LocalAlbumSet,一个是PicasaSource$EmptyAlbumSet,后面这个中实际没有资源,所以主要的资源在LocalAlbumset中。
在ComboAlbumSet中,reload时,分别调用LocalAlbumSet,PicasaSource$EmptyAlbumSet的reload。重点关注LocalAlbumset的reload。
什么时候开始执行reload呢?具体是TimeLineDataLoader的resume方法执行时,会创建ReloadTask,其中mSource就是ComboAlbumSet。
ComboAlbumSet中,重点是LocalAlbumset的reload,完成具体loader是AlbumsLoader这个Job,这个job会先通过查询数据库得到包含image、video数据的记录,这里的类型mType是MEDIA_TYPE_ALL。
对数据库的查询,是查ImageColumns.BUCKET_ID,FileColumns.MEDIA_TYPE,ImageColumns.BUCKET_DISPLAY_NAME这三列,并且按照bucketID分组。
其中bucketdisplayname是图片或者视频对应文件夹的名字,bucketid是这个文件夹对应path的hash值。
根据类型LocalAlbumset包含多个LocalMergeAlbum,LocalMergeAlbum中包含了两种类型的LocalAlbum,一种type是image,一种type是video。
具体的图片、视频就是根据Localalbum的getMediaItem方法查询到的,由查询返回的cursor来创建具体的LocalImage,Localvideo,对象。
- AlbumsetPage,相册集界面
根据DataManager.INCLUDE_ALL获取mediapath,
getDataManager().getTopSetPath(DataManager.INCLUDE_ALL)返回值跟TimeLinePage是一样的都是path=/combo/{/local/all,/picasa/all},对应的MediaSet是ComboAlbumSet。
Albumsetpage这个页面的dataloader是AlbumsetDataLoader,它的resume中会执行相应的mediaset的reload。具体就是对应了ComboAlbumSet的reload,其中子集LocalAlbumset包含了主要的数据项。
Localalbumset的具体reload跟TimeLinepage是一致的,不在赘述,另外在TimeLinepage已经加载过数据后,并且数据没有dirty,实际Albumsetpage是不用在去做重复加载的操作的。
3,VideoSet,视频集界面
首先根据DataManager.INCLUDE_ALL,获取到的basepath是:
String basePath = getDataManager().getTopSetPath(DataManager.INCLUDE_ALL);
值是/combo/{/local/all,/picasa/all},
通过FilterUtils.CLUSTER_BY_VIDEOS切换后,
String newPath = FilterUtils.switchClusterPath(basePath, clusterType);
值是newPath=/local/video/-1。
然后通过newPath=/local/video/-1这个path获取Mediaset。
具体函数:mMediaSet = mActivity.getDataManager().getMediaSet(mMediaSetPath);
这个/local/video/-1 path的前缀是local,所以其匹配的Mediasource是LocalSource。
接着调用的是Localsource的CreateMediaObject。
mMatcher.match(path)=3,就是LOCAL_VIDEO_ALBUM,所以创建的对应mediaset是
new LocalAlbum(path, app, mMatcher.getIntVar(0), false);
最后通过AlbumDataLoader的resume启动ReloadTask执行reload,会调用LocalAlbum的reload。
根据以上数据结构分析
移动videoset到albumset理论思路:把videoset移到albumset的实现思路:通过跟startVideopage相同的参数来生成相应的mediaset就是localalbum,然后把生成的视频集的localalbum添加到albumsetpage对应的集合(这个集合是comboalbumset中的localalbumset中的localmergealbum)中,有点绕。
一句话,理论分析是添加localmergealbum中,并且要在albumsetpage生成这个集合后,执行具体加载前添加,这样就不用考虑videoset的具体加载了,它会自动按albumset中的流程走。
具体位置可以在LocalAlbumset中的reload函数中,在albumsloader这个job执行结束,onfeaturedone返回后,也即是拿到了mLoaderBuffer数据,把videoset添加到这个mLoaderBuffer列表中。
因为localmergealbum跟localalbum是同级的,理论上可以直接把视频集的localalbum直接移动到localalbumset中。
依据以上分析,最终code完成。