浅析Android MediaProvider之二

MediaProvider 的实质是 Android 的 Core Applications 之一,和 Market 的 app 一样,并无神秘之处,其重要性就是提供了对 media 的操作,而刨根究底,这一操作正是通过同名类 MediaProvider 来实现的。

查阅该类源码,规模不小,再加以纠缠着内部类,第一眼很容易发懵,耐下性子整理出类图如下。正所谓“一个好汉三个帮”,单打独斗固然可以呈现出盖世英雄之势,但是若能团结众人,融合各方能力则能成就一番霸业。史书上的股市是这样,软件开发也如此,大到一个软件产品需要团队来开发,小到一个细微功能也是需要若干相关类来协同。此间利害可以由类图一目了然。【注意:下图中组合关系的方向是错误的,因为不便更新图片,请读者理解。特此声明 2012/02/02】

MediaProvider Class Diagram

MediaProvider Class Diagram

Android 在数据存储方面给出了四个建议,其中 Database 和 Preferences 用处最广,而 MediaProvider 正是采用了 Database 保存 media 的信息。在 Android 中,凡出现 SQLite 的地方,几乎就可以找到 SQLiteOpenHelper 的影子,在 MediaProvider 中一样如此。根据 Reference 的介绍可以知道该类的用途:

this class takes care of opening the database if it exists, creating it if it does not, and upgrading it as necessary

从类图中可以看到其结果比较简单,onCreate 和 onUpgrade 执行创建和升级的操作,显得较为简单,相较之下 onOpen 方法就要复杂一下。首先要明白该方法的目的是什么。通过注释可以知道其做两件事情,第一是更新数据库文件的修改时间,第二是删除多余的、旧的数据库。

此处的删除操作,为的是“垃圾回收”,以便让出存储空间。那么究竟什么是“旧”?什么是多余?这里须依照一个策略,那就是 LRU,LRU 是 Least Recently Uesd 的简写,通过该策略将两个月内未访问的数据库一概清除,执行完以后再判断剩下的数据库个数是否超出了限制,–Android 为每个外部存储设备建立一个独立的数据库,即 SDCard A 的信息是保存在一个数据库,SDCard B 则是保存在另一个数据库。如果超出限制,则从这些数据库中找出时间最早的一个,删除它,然后继续循环。

这里需要提醒一点,不管怎么删除数据库,内部存储对应的数据库是不删除的,–因为外部存储可能经常被用户插拔不同的 SDCard,而内部存储则是不会被替换的。

13 Comments

e3629 7 月, 2010 at 12:10 下午

看到着,我发晕 ,不知是自己的内功太浅还是,此文没有把思路说明白

Xu Haojie29 7 月, 2010 at 1:05 下午

Sorry,是我没能理解透彻,故不能把来龙去脉解释清楚

e361 8 月, 2010 at 7:28 下午

支持下,能把mediascanner和mediaprovider 写清楚点

cpu0oop3 11 月, 2010 at 10:56 上午

请教个问题,外部存储的数据库生成的名称如何得到,他是存储在某个文件里面,还是其他什么方法得到的,谢谢!

Xu Haojie5 11 月, 2010 at 8:00 下午

抱歉,对你的问题无能为力,我对此的认识还停留在大半年前撰写此文的水平,Sorry。

cpu0oop9 11 月, 2010 at 4:09 下午

哦,没关系,还是谢谢你的回复。

JeffyChen7 4 月, 2011 at 1:16 下午

String path = Environment.getExternalStorageDirectory().getPath();
int volumeID = FileUtils.getFatVolumeId(path);
if (LOCAL_LOGV) Log.v(TAG, path + ” volume ID: ” + volumeID);

// generate database name based on volume ID
String dbName = “external-” + Integer.toHexString(volumeID) + “.db”;
db = new DatabaseHelper(getContext(), dbName, false);

开心果24 11 月, 2011 at 2:08 下午

这代码什么意思啊?做什么的?

sorry5 11 月, 2010 at 5:27 下午

你还是不要贴出来的好,浪费服务器空间!

Xu Haojie5 11 月, 2010 at 8:02 下午

尽管服务器空间有限,但还是决定保留你的评论。

开心果24 11 月, 2011 at 2:12 下午

楼主,知道怎么删除相框里的图片了么?

divce2 2 月, 2012 at 10:41 上午

UML图画错了吧 Worker和 MediaProvider是组和关系没错,但是Worker是子 ,MediaProvider是父吧。如果我说错了请给我纠正,谢谢

Xu Haojie2 2 月, 2012 at 11:25 上午

谢谢指正,我特意去查询了composition,确认图中的方向是错误的。再次感谢,澄清了我对UML的误读,同时对此前读者道歉。

Leave a comment

Your comment