Android MediaScanner 扫描流程

android MediaScanner 扫描调用的时序图:

Created with Raphaël 2.1.0 MediaScanner Receiver.java MediaScanner Receiver.java MediaScanner Service.java MediaScanner Service.java Media Scanner.java Media Scanner.java android_ media_Media Scanner.cpp android_ media_Media Scanner.cpp Stagefri ghtMedia Scanner.cpp Stagefri ghtMedia Scanner.cpp Media Scanner.cpp Media Scanner.cpp Stagefright Metadata Retriever.cpp Stagefright Metadata Retriever.cpp 1,received mounted broadcast 2,scan 3,create MediaScanner 4,create MyMediaScan nerClient MyMedia ScannerClient 5,native_init 6,native_setup 7,create Stage fright MediaScanner 8,scanDirectories 9,initialize 10,prescan 11,process Directory 12,create MyMedia ScannerClient MyMedia ScannerClient 13,MyMedia Scanner Client(native) reflection of MyMedia Scanner Client(java) 14,processDirectory 15,doPro cess Directory 16,doPro cessDirec toryEntry 17,MyMediaScanner Client->scanFile 18,MyMedia Scanner Client->scanFile 19,doScanFile 20,beginFile Audio or Video follow 21,processFile 22,processFile 23,new Media Metadata Retriever 24,setData Source 25,extract Metadata 26,MyMediaScanner Client->setMimeType 27,extract Metadata 28,MyMediaScanner Client->addStringTag 29,postscan Scan 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 讲扫描到的信息插入到数据库中

你可能感兴趣的:(播放器)