浅析Android MediaProvider之二
MediaProvider 的实质是 Android 的 Core Applications 之一,和 Market 的 app 一样,并无神秘之处,其重要性就是提供了对 media 的操作,而刨根究底,这一操作正是通过同名类 MediaProvider 来实现的。
查阅该类源码,规模不小,再加以纠缠着内部类,第一眼很容易发懵,耐下性子整理出类图如下。正所谓“一个好汉三个帮”,单打独斗固然可以呈现出盖世英雄之势,但是若能团结众人,融合各方能力则能成就一番霸业。史书上的股市是这样,软件开发也如此,大到一个软件产品需要团队来开发,小到一个细微功能也是需要若干相关类来协同。此间利害可以由类图一目了然。【注意:下图中组合关系的方向是错误的,因为不便更新图片,请读者理解。特此声明 2012/02/02】
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,而内部存储则是不会被替换的。
看到着,我发晕 ,不知是自己的内功太浅还是,此文没有把思路说明白
Sorry,是我没能理解透彻,故不能把来龙去脉解释清楚
支持下,能把mediascanner和mediaprovider 写清楚点
请教个问题,外部存储的数据库生成的名称如何得到,他是存储在某个文件里面,还是其他什么方法得到的,谢谢!
抱歉,对你的问题无能为力,我对此的认识还停留在大半年前撰写此文的水平,Sorry。
哦,没关系,还是谢谢你的回复。
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);
这代码什么意思啊?做什么的?
你还是不要贴出来的好,浪费服务器空间!
尽管服务器空间有限,但还是决定保留你的评论。
楼主,知道怎么删除相框里的图片了么?
UML图画错了吧 Worker和 MediaProvider是组和关系没错,但是Worker是子 ,MediaProvider是父吧。如果我说错了请给我纠正,谢谢
谢谢指正,我特意去查询了composition,确认图中的方向是错误的。再次感谢,澄清了我对UML的误读,同时对此前读者道歉。