JNI中l(wèi)oad與loadLibrary的區(qū)別

  • load 和loadLibrary都是System類(lèi)的方法
  • 作用都是加載需要使用的庫(kù)文件
  • 類(lèi)加載器都是通過(guò)Reflection.getCallerClass()獲取
  • 最終調(diào)用的是nativeLoad方法
  • load需要傳入加載類(lèi)的絕對(duì)地址,loadLibrary只需傳入類(lèi)文件名

load方法源碼

System中-->
  @CallerSensitive
    public static void load(String filename) {
        Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
    }

//最終調(diào)用Runtime中的load0方法,重點(diǎn)看load0即可
Runtime-->

synchronized void load0(Class<?> fromClass, String filename) {
        if (!(new File(filename).isAbsolute())) {//此處判斷如果文件路徑名是否為絕對(duì)路徑,不是則拋出異常
            throw new UnsatisfiedLinkError(
                "Expecting an absolute path of the library: " + filename);
        }
        if (filename == null) {
            throw new NullPointerException("filename == null");
        }
        String error = nativeLoad(filename, fromClass.getClassLoader());
        if (error != null) {
            throw new UnsatisfiedLinkError(error);
        }
    }

load總結(jié):

  • load方法中會(huì)測(cè)試傳入的抽象路徑名是否為絕對(duì)路徑。
  • 絕對(duì)路徑名的定義取決于系統(tǒng)。
  • 在A(yíng)ndroid上,絕對(duì)路徑以字符“ /”開(kāi)頭。
loadLibrary源碼
System-->
 @CallerSensitive
    public static void loadLibrary(String libname) {
        Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
    }

Runtime-->
//最終調(diào)用Runtime中l(wèi)oadLibrary0
 private synchronized void loadLibrary0(ClassLoader loader, Class<?> callerClass, String libname) {
        if (libname.indexOf((int)File.separatorChar) != -1) {//此方法判斷l(xiāng)ibname中是否含有分隔符,有的話(huà)就拋出異常
            throw new UnsatisfiedLinkError(
    "Directory separator should not appear in library name: " + libname);
        }
        String libraryName = libname;
        // Android-note: BootClassLoader doesn't implement findLibrary(). http://b/111850480
        // Android's class.getClassLoader() can return BootClassLoader where the RI would
        // have returned null; therefore we treat BootClassLoader the same as null here.
        if (loader != null && !(loader instanceof BootClassLoader)) {
            String filename = loader.findLibrary(libraryName);
            if (filename == null) {
                // It's not necessarily true that the ClassLoader used
                // System.mapLibraryName, but the default setup does, and it's
                // misleading to say we didn't find "libMyLibrary.so" when we
                // actually searched for "liblibMyLibrary.so.so".
                throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
                                               System.mapLibraryName(libraryName) + "\"");
            }
            String error = nativeLoad(filename, loader);
            if (error != null) {
                throw new UnsatisfiedLinkError(error);
            }
            return;
        }

        // We know some apps use mLibPaths directly, potentially assuming it's not null.
        // Initialize it here to make sure apps see a non-null value.
        getLibPaths();
        String filename = System.mapLibraryName(libraryName);
        String error = nativeLoad(filename, loader, callerClass);
        if (error != null) {
            throw new UnsatisfiedLinkError(error);
        }
    }

解析:

*  libname.indexOf((int)File.separatorChar) != -1 

File-->
   public static final char separatorChar = fs.getSeparator();
  • 獲取文件中的文件名分隔符,強(qiáng)轉(zhuǎn)成unicode值
  • 判斷l(xiāng)ibname中是否含有分隔符,不含有則返回-1.
  • 所以不等于-1則拋出異常

loadLibrary總結(jié)

  • 需傳入文件名的名稱(chēng)部分
  • 通過(guò)BootClassLoader子類(lèi)的findLibrary方法返回絕對(duì)地址
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容