Android MediaScanner 扫描流程

来源:互联网 发布:用vb制作倒计时 编辑:程序博客网 时间:2024/05/16 11:33

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 讲扫描到的信息插入到数据库中
原创粉丝点击