初步理解Android的MediaScanner(2)

        根据分析可知,MediaScannerRecevier接收广播请求之后由MediaScannerService完成扫描信息,并添加信息到媒体数据库中。同时MediaScannerProvider可以对数据库进行操作,主要涉及的查询、删除、更新等等。

        MediaScannerService中的scan()函数中创建MediaScanner对象,完成扫描任务。主要分析MediaScanner的工作原理,从JAVA,JNI,和Native层三层分析。

        MediaScanner对象创建后,由于是在MediaScannerService中的scan()完成的,所以MSS调用MediaScanner.scanDirectories方法开展扫描工作。

       1. MediaScanner.java中scanDirectories函数分析:

       void scanDirectories(String[] directories, String volumeName) {

     // a: 初始化:初始化URi,扫描时需要把文件信息插入到媒体库中,媒体库对video,audio,image等等的文件都有对应的表,这些表的地址是由URi表示的,首先要做的就是完成这些表的初始化。

       initialize(volumeName);

   // b: 进入到扫描阶段,扫描时会有三个步骤,首先是预处理prescan(),然后是processDirecotory()扫描中扫尾工作postscan().

   prescan():保存开始的已有的一些数据库文件信息记录,是扫描前数据库的初态,扫描的过程完成后,会扫描出新的信息,这样就可以能和原来的不一样,这是postscan().开始工作,完成新的数据库的更新。

以上分析的是java层中主要的3点内容。而processDirecotory()这个重点的处理函数是由native层完成的。

 

     2.MediaScanner的native层上的processDirectory(),和native_init,native_setup函数分析。

    static void

    android_media_MediaScanner_native_init(JNIEnv *env)

  {//取得java中mNativeContext的内容,在之后的操作时会把native对象指针放在这个这个mNativeContext中。

    jclass clazz = env->FindClass(kClassMediaScanner);

   fields.context = env->GetFieldID(clazz, "mNativeContext", "I");

  }

  在这个函数中得到的android_media_MediaScanner_native_setup会创建native层的MediaScanner,根据代码可知其实是创建的是StagefrightMediaScanner对象完成任务的

android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz) 

{LOGV("native_setup");

MediaScanner *mp = new StagefrightMediaScanner;

if (mp == NULL) {

jniThrowException(env, kRunTimeException, "Out of memory");

return;

env->SetIntField(thiz, fields.context, (int)mp);

}

    native_init和 native_setup是一起完成任务的。init获取到java中的设备上下文环境,setup创建native层的MediaScannert对象,同时以把这个对象指针保存在mcontext中,这样就可以native MediaScanner完成工作。在native层代码分析中创建出的对象new StagefrightMediaScanner再继续工作。

 

 

 

 

 

你可能感兴趣的:(初步理解Android的MediaScanner(2))