前言

接上文《MediaScanner源码JNI介绍》介绍register_android_media_MediaScanner的registerNativeMethods()注册是在android_media_MediaPlayer.cpp中JNI_OnLoad,上次有个疑惑,哪何时加载JNI_OnLoad()?

// This function only registers the native methods, and is called from
// JNI_OnLoad in android_media_MediaPlayer.cpp
int register_android_media_MediaScanner(JNIEnv *env)
{
    return AndroidRuntime::registerNativeMethods(env,
                kClassMediaScanner, gMethods, NELEM(gMethods));
}

流水账而已,勿喷!

正文

在android_media_MediaPlayer.cpp的JNI_OnLoad()中

jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    //略
    if (register_android_media_ImageWriter(env) != JNI_OK) {
        goto bail;
    }
    if (register_android_media_ImageReader(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaPlayer(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaRecorder(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaScanner(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaMetadataRetriever(env) < 0) {
        goto bail;
    }
    if (register_android_media_ResampleInputStream(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaProfiles(env) < 0) {
        goto bail;
    }
    if (register_android_mtp_MtpDatabase(env) < 0) {
        goto bail;
    }
    if (register_android_mtp_MtpDevice(env) < 0) {
        goto bail;
    }
    if (register_android_mtp_MtpServer(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaCodec(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaSync(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaExtractor(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaMuxer(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaCodecList(env) < 0) {
        goto bail;
    }
    if (register_android_media_Crypto(env) < 0) {
        goto bail;
    }
    if (register_android_media_Drm(env) < 0) {
        goto bail;
    }
    if (register_android_media_Descrambler(env) < 0) {
        goto bail;
    }
    if (register_android_media_MediaHTTPConnection(env) < 0) {
        goto bail;
    }
    result = JNI_VERSION_1_4;
bail:
    return result;
}

注册了很多,那你是否很好奇过,那啥时候会调用JNI_OnLoad()呢?

其实一开始我是没看懂,后面搜索了一下[media_jni]

base/media/java/android/media/CamcorderProfile.java:        System.loadLibrary("media_jni");
base/media/java/android/media/CameraProfile.java:        System.loadLibrary("media_jni");
base/media/java/android/media/DecoderCapabilities.java:        System.loadLibrary("media_jni");
base/media/java/android/media/EncoderCapabilities.java:        System.loadLibrary("media_jni");
base/media/java/android/media/ImageReader.java:        System.loadLibrary("media_jni");
base/media/java/android/media/ImageWriter.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaCodec.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaCodecList.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaCrypto.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaDescrambler.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaDrm.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaExtractor.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaHTTPConnection.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaMetadataRetriever.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaMuxer.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaPlayer.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaRecorder.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaScanner.java:                Log.v(TAG, "loadLibrary media_jni : ");
base/media/java/android/media/MediaScanner.java:        System.loadLibrary("media_jni");
base/media/java/android/media/MediaSync.java:        System.loadLibrary("media_jni");
base/media/java/android/media/ResampleInputStream.java:        System.loadLibrary("media_jni");
base/media/java/android/media/midi/MidiDevice.java:        System.loadLibrary("media_jni");
base/media/java/android/mtp/MtpDatabase.java:        System.loadLibrary("media_jni");
base/media/java/android/mtp/MtpDevice.java:        System.loadLibrary("media_jni");
base/media/java/android/mtp/MtpServer.java:        System.loadLibrary("media_jni");

MediaPlayer和MediaScanner等类都加载了[media_jni]库。

按照上面的意思,是不是只要其中一个加载[media_jni]库,都会去调用JNI_OnLoad()?

为了验证,我们可以加个日志打印一下。

我再MediaScanner.java中和android_media_MediaPlayer.cpp的JNI_OnLoad()中加了打印,开机后MediaProvider通知MediaScanner去扫描。下面日志打印:

MediaScanner: loadLibrary media_jni : 
MediaPlayer-JNI: JNI_OnLoad
MediaScannerJNI: native_init

从上面可以看出,执行MediaScanner的静态代码块加载so后马上执行了android_media_MediaPlayer.cpp的JNI_OnLoad()。

参考文章

  1. MediaScanner源码JNI介绍

相关文章

暂无评论

none
暂无评论...