[android_gallery_4.0]gallery主要功能流程介绍

最近都在研究android4.0的gallery,深感复杂,写下文档,先贴着一部分先。欢迎大家看后交流,乐意接受批评指正。

1.1.1 进入gallery

进行如下关键操作。

l        先进入gallery’中处理。Gallery中initializeByIntent中最终会调用启动albumset,代码如下。

Bundledata = new Bundle();

       data.putString(AlbumSetPage.KEY_MEDIA_PATH,

               getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));

       getStateManager().startState(AlbumSetPage.class, data);

l        初始化view,创建albumsetview并注册其侦听者,该侦听者负责侦听用户点击触摸操作。

l        创建GLView类的对象,在该对象重载实现onlayout()以及render函数。其中onlayout()在每次进入这个主界面时调用,render()在每次该界面视图改变时调用,例如触摸等操作使得界面视图改变调用render来重绘。

l        创建界面上的其他元素。

l        创建过渡动画。

 

1.1.2 退出gallery

l        调用onbackpressed退出。

l        最终执行退出操作是由StateManager的finishState。该函数会先出栈一个activitystate,后再判断是否栈为空,为空才真正终止应用退出。

 

1.1.3 打开相册

在点击进入相册前进行如下操作。

l        若进入的相册下一级已经没有相册了,那就启动albumpage。

l        若进入的相册下一级仍有相册了,那就启动albumsetpage。

进入albumpage后,主要步骤跟进入gallery时差不多。

1.1.4 打开相片或视频

1)打开图片见3.1.5。

2)打开视频见下面分析。主要操作见下面。

l        ControllerOverlay用于播放控件的实现,诸如时间条,屏幕中间显示的播放状态按钮等等。

l        加载各种view,控件。

l        Movieplayer中的Bookmarker是个书签功能,看代码就是负责保存本次播放的位置,等挂起后重新进入gallery可以从上一次播放位置继续播放。

1.1.5 播放幻灯片

主要操作如下。

l        初始化数据以及view。

l        指定播放幻灯片按什么顺序播放,或是随机,或是顺序。

1.1.6 删除图片或视频

主要操作如下。

l        删除操作在三个地方有,gallery主界面、相册内界面、图片浏览界面,他们都是由界面上方的actionbar按钮触发。

l        Albumsetpage、albumpage均是创建ActionModeHandler来实现加载这个actionbar。Photopage是通过创建MenuExecutor来加载这个actionbar。另外这个actionbar同时包括actiobar的其他操作,诸如裁剪、编辑等等。

l        最终的删除操作是通过获取mediaobject对象,对其进行操作实现的。Mediaobject同时是mediaset、mediaitem的父类,多态性就能保证对相册或是相片进行删除操作。删除操作最终通过conresolver.delete实现。

1.1.7 开机与media相关的数据库流程

流程见下。

l        创建mediaprovider。Mediaprovider中oncreate主要做如下处理。

n        挂载内部存储器,创建内部存储器的数据库。

n        创建侦听者来侦听卸载存储器的事件,包括卸载内部存储器以及外部存储器。

n        挂载外部存储器,创建外部存储器的数据库。

n        创建线程,用于处理更新缩略图的请求。缩略图请求分为两种,一种是图片缩略图,处理原则是FIFO,先请求先处理;另一种是音乐专辑缩略图,处理原则是LIFO,后请求先处理。

 

l        与2.3一样,先通过mediascanerreceiver接收到Intent.ACTION_MEDIA_MOUNTED这个加载intent,调用scan对全盘媒体文件进行扫描。

l        接着调用到mediascannerservice。ServiceHandler中对指定路径进行扫描。调用到mediascannerservice.scan()。扫描前发送Intent.ACTION_MEDIA_SCANNER_STARTED广播,接着创建mediascanner进行扫描,扫描后发送Intent.ACTION_MEDIA_SCANNER_FINISHED。接收这两个广播的地方找不到。应该是用于提示外部的应用扫描的开始以及结束。

l        在扫描前会插入数据库一条记录,之后就删除该条记录。为什么要在之前插入一条记录,之后就删除这条记录,并且只是获取了uri,并没对这个uri进行操作,看不懂。代码如下。

 

UriscanUri = getContentResolver().insert(MediaStore.getMediaScannerUri(), values);

//...

getContentResolver().delete(scanUri,null, null);

        调用mediascanner.scanDirectories扫描所有目录。

          mediascanner.scanDirectories中,有如下关键操作。

n        Initalize():初始化各个媒体uri。总共有如下uri。

mAudioUri

mVideoUri

mImagesUri

mThumbsUri

mFilesUri

n        Prescan():扫描mFilesUri所示的文件。写入filecache中。同时计算mImagesUri的文件数。

n        processDirectory():遍历扫描所有路径。具体进入c++代码,看不懂。

n        Postscan():删除掉文件系统中不存在但数据库中存在的文件项,此删除为删除数据库中记录项。

1.1.8    Filemanager中删除媒体文件

删除单个文件主要流程见下。

在Filemanager中,主要操作流程如下。

l        删除该文件。

l        FileMgrMenuUtil.notifyFileSystemChanged中发送Intent.ACTION_MEDIA_SCANNER_SCAN_FILE通知删除文件成功。Mediareceiver接收到就交给mediascannerservice进行scanfile()处理。

n        Mediascannerservice.scanfile(),最终调用到Mediascanner.scansinglefile()处理。主要进行如下处理。

n        初始化各种扫描需要的东西,如路径等。

n        Prescan():更新媒体文件的filecache。Filecache是一个索引表,存放媒体文件的关键数据,以提高访问这些文件的速度。

n        Doscanfile():在这里主要是置标志位表示已经在文件系统找到该文件。

l        均是调用mediaobject.delete()完成删除操作,其实最终调用的是mediaobject派生出的mediaset、mediaitem。而跟进代码最终是在mediaprovider.delete处理。

l        Mediaprovider.delete()主要是删除数据库中该条记录。

 

在Gallery中,主要需要注意流程如下。

l        均是调用mediaobject.delete()完成删除操作,其实最终调用的是mediaobject派生出的mediaset、mediaitem。而跟进代码最终是在mediaprovider.delete处理。

l        Mediaprovider.delete()主要是删除数据库中该条记录。

l        但是不能找到地方处理删除文件操作。

 

 

删除目录。

在filemanager中,流程稍有不同,主要见以下。

l        会调用到RecursiveDeleteTask线程进行递归删除目录下文件的处理。

l        FileMgrMenuUtil.notifyFileSystemChanged中发送Intent.ACTION_MEDIA_MOUNTED通知删除文件夹成功。Mediascannerservice进行scan()处理。其主要操作跟“开机与media相关的数据库流程”内的Mediascannerservice.scan()大同小异,区别在与扫描范围的不同。

 

在gallery中,操作见上面的删除单个文件操作。

1.1.9    Filemanager中移动媒体文件

移动单个文件。

在filemanager中,主要注意以下。

l        交由MoveTask线程处理,线程中通过file.renameto()来实现将文件移动到另一个地方,这个方法只是更改了原来文件路径。

l        FileMgrMenuUtil.notifyFileSystemChanged中发送Intent.ACTION_MEDIA_SCANNER_SCAN_FILE通知移动文件成功。接着Mediascannerservice同样进行单个文件扫描处理。

 

移动一整个目录。

在filemanager中,主要注意以下。

l        主要通过以下数据结构来存放待处理的文件列表。

private ArrayList<FileInfo>mCheckedFileList = new ArrayList<FileInfo>();

l        同样还是MoveTask线程处理这些文件。

l        FileMgrMenuUtil.notifyFileSystemChanged中发送Intent.ACTION_MEDIA_MOUNTED通知移动文件夹成功。Mediascannerservice进行scan()处理。

1.1.10 Filemanager中重命名媒体文件

重命名单个文件与文件夹操作基本一致。

Filemanager中,主要操作流程如下。

l        同样使用file.renameto()进行重命名文件操作。

l        同样使用FileMgrMenuUtil.notifyFileSystemChanged发送intent消息通知重命名操作,使得Mediascannerservice再去扫描。这里发送的intent消息,重命名单个文件与重命名文件夹是不一样的,与之前区别一样。

1.1.11 Filemanager中复制媒体文件

复制单个文件。

在filemanager中,主要操作流程如下。

l        检查目的地址空间足够与否。

l        同样使用FileMgrMenuUtil.notifyFileSystemChanged发送intent消息通知重命名操作,使得Mediascannerservice再去扫描。这里发送的intent消息,重命名单个文件与重命名文件夹是不一样的,与之前区别一样。

 

复制目录。与单个文件操作基本一致。主要见以下。

l        递归实现copy。

1.1.12 增加媒体文件

在camera拍摄一张照片后,主要进行如下操作。

l        生成这个jpeg格式的图片。

l        ContentResolver中插入一条关于这照片的记录到对应数据库中。

posted on 2014-04-30 15:50  小尾巴猴子  阅读(593)  评论(0编辑  收藏  举报

导航