显示标签为“database”的博文。显示所有博文
显示标签为“database”的博文。显示所有博文

2013年11月19日星期二

How to detect Android Cursor leak

Summary:This post tells the theory of detecting SQLite database Cursor leak of your Android app, alongside some common mistake examples. Some leaks are hardly noticable in the code until memory errors happen. This sort of method can be applied to other kinds of resources leak as well.

Cursor leak means that you have opened a Cursor object, which is usually associated with a portion of memory, but fail to close it before you lost referece to it. If it do happens and is repeated several hundreds of times, you would finally be unable to query SQLite database, and exception like this would appear. The log says 866 Cursors are opened and memory allocation of 2MB is failed.

2013年10月27日星期日

专题合集:深入Android媒体存储服务





Android 有一套媒体存储服务,进程名是 android.process.media,主要负责把磁盘中的文件信息保存到数据库当中,供其他 APP 使用以及 MTP 模式使用。这里包含了数据库管理、磁盘文件遍历扫描、多媒体文件解析等几个部分,下面文章分别覆盖了这些内容:

2013年10月23日星期三

深入Android媒体存储服务(二): 磁盘扫描流程

简介:
本文是《深入Android媒体存储服务》系列第二篇,简要介绍媒体存储服务扫描文件的流程。文中介绍的是 Android 4.2。
Android 有一套媒体存储服务,进程名是 android.process.media,主要负责把磁盘中的文件信息保存到数据库当中,供其他 APP 使用以及 MTP 模式使用。因此如何保持数据库和磁盘文件保持一致非常关键,这个就是媒体存储服务中 MediaScanner 的工作。

媒体文件扫描流程



2013年7月1日星期一

深入Android媒体存储服务(一): APP与媒体存储服务的交互

简介:
本文介绍如何在 Android 中,开发者的 APP 如何使用媒体存储服务(包含MediaScanner、MediaProvider以及媒体信息解析等部分),包括如何把 APP 新增或修改的文件更新到媒体数据库、如何在多媒体应用中隐藏 APP 产生的文件、如何监听媒体数据库的变化等等。
Android 原生有一套媒体存储服务,进程名是 android.process.media,主要负责把磁盘中的文件信息保存到数据库当中,供其他 APP 使用以及 MTP 模式使用。因此 APP 可以随时快速查询到机器上有多少音乐,音乐的时长、标题、艺术家、专辑封面都可以获取到。下面就介绍我们开发的 APP 如何与这个媒体存储服务打交道。关于媒体存储服务详细分析,请查看本系列第二篇文章:磁盘扫描流程。
Note:MTP 模式是 Android 3.0 开始引入的,其数据来源于媒体存储服务。

隐藏多媒体文件

应用场景:APP 产生了图片/音乐/视频类文件,不想让它显示在图库/音乐播放器。市面上有不少游戏,它的图片和音效文件没有做隐藏,出现在用户的图库/音乐播放器当中,引起用户反感。如果用户把它删除了,又可能会影响 APP 正常运行。

2013年6月13日星期四

SQLite 加入自定义函数

简介:

SQLite 内置函数比较有限,有时通过添加自定义函数(User-Defined Fuctions)的方式可以实现一些通过普通 SQL 操作无法实现或者实现很麻烦的功能;也可以替换 SQLite 原有的内置函数,使其符合我们的要求。本文侧重说明在 Android 环境下的做法。

现在假设我们现在要在 Android 系统的视频播放器增加一个按照文件扩展名排序的功能,如果不是用自定义函数,就需要先从多媒体数据库中查询出来视频的路径,然后取出视频文件的扩展名并进行排序,因为查询得到的 Cursor 对象不可写,所以需要生成一个 MatrixCursor,把排序后的数据写入,最后返回这个 MatrixCursor。伪代码表示如下:

public Cursor getSortedByFileExtensionCursor() {
    Cursor rawCursor = queryVideoFileNameFromDb(); // 从数据库查询出 id 和路径
    HashMap idAndExtensionMap = getVideoFileExtension(rawCursor); // 获取 id 和扩展名的 HashMap
    Cursor result = sortAndCreateNewMatrixCursor(idAndExtensionMap); // 对扩展名进行排序,生成 MatrixCursor 作为结果
    return result;
}

而如果我们能够向 SQLite 注册一个自定义函数,很多类似问题就要简单不少。