android MediaScanner 扫描调用的时序图:
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媒体扫描
该函数是耗时最长的,主要分两种,如果是目录的话,就递归调用,如果是文件的话就