Android MediaScanner 扫描流程

本文详细剖析了Android系统的MediaScanner工作原理,从广播接收、预扫描到目录处理等环节进行了全面解读,并对关键函数及其作用进行了说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

android MediaScanner 扫描调用的时序图:

Created with Raphaël 2.1.0MediaScannerReceiver.javaMediaScannerReceiver.javaMediaScannerService.javaMediaScannerService.javaMediaScanner.javaMediaScanner.javaandroid_media_MediaScanner.cppandroid_media_MediaScanner.cppStagefrightMediaScanner.cppStagefrightMediaScanner.cppMediaScanner.cppMediaScanner.cppStagefrightMetadataRetriever.cppStagefrightMetadataRetriever.cpp1,receivedmountedbroadcast2,scan3,createMediaScanner4,create MyMediaScan nerClientMyMediaScannerClient5,native_init6,native_setup7,create StagefrightMediaScanner8,scanDirectories9,initialize10,prescan11,processDirectory12,create MyMediaScannerClientMyMediaScannerClient13,MyMediaScannerClient(native) reflection of MyMediaScannerClient(java)14,processDirectory15,doProcessDirectory16,doProcessDirectoryEntry17,MyMediaScannerClient->scanFile18,MyMediaScannerClient->scanFile19,doScanFile20,beginFileAudio or Video follow21,processFile22,processFile23,new MediaMetadataRetriever24,setDataSource25,extractMetadata26,MyMediaScannerClient->setMimeType27,extractMetadata28,MyMediaScannerClient->addStringTag29,postscanScan finished

android MediaScanner 代码具体分析:

引言:

 * The way the scan currently works is:
 * - The Java MediaScannerService creates a MediaScanner (this class), and calls
 *   MediaScanner.scanDirectories on it.
 * - scanDirectories() calls the native processDirectory() for each of the specified directories.
 * - the processDirectory() JNI method wraps the provided mediascanner client in a native
 *   'MyMediaScannerClient' class, then calls processDirectory() on the native MediaScanner
 *   object (which got created when the Java MediaScanner was created).
 * - native MediaScanner.processDirectory() calls
 *   doProcessDirectory(), which recurses over the folder, and calls
 *   native MyMediaScannerClient.scanFile() for every file whose extension matches.
 * - native MyMediaScannerClient.scanFile() calls back on Java MediaScannerClient.scanFile,
 *   which calls doScanFile, which after some setup calls back down to native code, calling
 *   MediaScanner.processFile().
 * - MediaScanner.processFile() calls one of several methods, depending on the type of the
 *   file: parseMP3, parseMP4, parseMidi, parseOgg or parseWMA.
 * - each of these methods gets metadata key/value pairs from the file, and repeatedly
 *   calls native MyMediaScannerClient.handleStringTag, which calls back up to its Java
 *   counterparts in this file.
 * - Java handleStringTag() gathers the key/value pairs that it's interested in.
 * - once processFile returns and we're back in Java code in doScanFile(), it calls
 *   Java MyMediaScannerClient.endFile(), which takes all the data that's been
 *   gathered and inserts an entry in to the database.

从上面可以看出media scanner流程的设计逻辑,下面有几点需要注意:

1,接收mount 广播

mediaScannerReceiver 接收外部设备广播后,通过mediaScannerService每次扫描外部的都从SD卡目录扫描,然后递归到U盘,若加快扫描速度,可以考虑只扫描U盘目录或者固定目录。

2,预扫描 prescan

该函数的作用就是在扫描之前把数据库中的信息提取并保存(包括媒体文件的路径,Metadata,所属表的URI),这个主要是为了扫描后更好的更新数据库。

3,processDirectory媒体扫描

该函数是耗时最长的,主要分两种,如果是目录的话,就递归调用,如果是文件的话就

a,先调用beginFile,该函数用来保存到数据库之前的缓存中,还用来判断当前文件是否被修改过,若修改过,继续调用扫描。
b,再调用processFile,该函数通过调用mediaRetriver获取ID3信息
c,最好调用endfile 讲扫描到的信息插入到数据库中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值