2

まず、System.java で、Runtime を呼び出して loadLibrary を呼び出します。

public static void loadLibrary(String libName) {
    SecurityManager smngr = System.getSecurityManager();
    if (smngr != null) {
        smngr.checkLink(libName);
    }
    Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
}

次に、VMStack.getCallingClassLoader() を呼び出して findLibrary を実行します。

void loadLibrary(String libraryName, ClassLoader loader) {
    if (loader != null) {
        String filename = loader.findLibrary(libraryName);
        if (filename == null) {
            throw new UnsatisfiedLinkError("Couldn't load " + libraryName + ": " +
                    "findLibrary returned null");
        }
        //....
    }
}

だから、私VMStack.getCallingClassLoader()は最も意味があると思います。しかし、その jni ファイルdalvik_system_VMStack.cppでは、Dalvik_dalvik_system_VMStack_getCallingClassLoader関数を学習するのは困難です。そして最後に、dalvik findLibrary の方法は?

static void Dalvik_dalvik_system_VMStack_getCallingClassLoader(const u4* args,
    JValue* pResult){
    ClassObject* clazz =
        dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame);

    UNUSED_PARAMETER(args);

    if (clazz == NULL)
        RETURN_PTR(NULL);
    RETURN_PTR(clazz->classLoader);
}
4

1 に答える 1

7

VMStack.getCallingClassLoader()現在のメソッドを呼び出したメソッドを宣言したクラスのクラスローダーを返します。つまり、関数が をfoo()呼び出すと、のクラス ローダーRuntime.loadLibrary()が返されます。foo

findLibraryすべてのポイントは、 のコンテキストではなく、 を呼び出した人のコンテキストでライブラリが確実にロードされるようにすることですjava.lang.Runtime

実際の作業を行うを呼び出すfindLibrary()によって実装される可能性が十分にあります。興味深い点は、引数からコンストラクター (またはから取得) に初期化されるwalk throughです。BaseDexClassLoaderDexPathList.findLibrary()nativeLibraryDirectorieslibraryPathBaseDexClassLoaderPathClassLoaderDexClassLoader

Android アプリについてはandroid.app.ApplicationLoaders、 を使用する をご覧くださいPathClassLoader。それを十分にさかのぼると、ディレクトリが から取得されていることがわかりますApplicationInfo.nativeLibraryDir

編集:コメントに対処するためにさらに深くなります...

/system/libjava.library.path、コア ライブラリがLD_LIBRARY_PATH環境変数から抽出するプロパティから取得されます。アプリ固有のライブラリ dir は、フレームワークによって構成されます。

コンストラクターはPackageManagerServicelib パスを に設定しmAppLibInstallDirsetInternalAppNativeLibraryPath()構成しますnativeLibraryDir

DexPathList.splitLibraryPath()java.library.pathパスを APK 固有のパスと結合します。注文に関する注意事項については、そこにあるコメントを参照してください。

于 2013-03-29T19:49:38.220 に答える