各安卓版本关于loadLibrary函数的实现区别(Implementation differences of loadlibrary function in Android versions)-安卓
各安卓版本关于loadLibrary函数的实现区别(Implementation differences of loadlibrary function in Android versions)
loadLibrary主要是在Runtime.java中实现,各个版本之间差异比较大,所以做个笔记来整理这些区别。
4.4 版本
源码:
Cross Reference: /libcore/luni/src/main/java/java/lang/Runtime.java
主要是这一块:
http://androidxref.com/4.4.4_r1/xref/libcore/luni/src/main/java/java/lang/Runtime.java#354
void loadLibrary(String libraryName, ClassLoader loader) {
355 if (loader != null) {
356 String filename = loader.findLibrary(libraryName);
357 if (filename == null) {
358 throw new UnsatisfiedLinkError("Couldn't load " + libraryName +
359 " from loader " + loader +
360 ": findLibrary returned null");
361 }
362 String error = doLoad(filename, loader);
363 if (error != null) {
364 throw new UnsatisfiedLinkError(error);
365 }
366 return;
367 }
368
369 String filename = System.mapLibraryName(libraryName);
370 List<String> candidates = new ArrayList<String>();
371 String lastError = null;
372 for (String directory : mLibPaths) {
373 String candidate = directory + filename;
374 candidates.add(candidate);
375
376 if (IoUtils.canOpenReadOnly(candidate)) {
377 String error = doLoad(candidate, loader);
378 if (error == null) {
379 return; // We successfully loaded the library. Job done.
380 }
381 lastError = error;
382 }
383 }
384
385 if (lastError != null) {
386 throw new UnsatisfiedLinkError(lastError);
387 }
388 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
389 }
其中关键的一部分代码是这个:
String filename = loader.findLibrary(libraryName);
357 if (filename == null) {
358 throw new UnsatisfiedLinkError("Couldn't load " + libraryName +
359 " from loader " + loader +
360 ": findLibrary returned null");
361 }
接着去寻找findLibrary。
http://androidxref.com/4.4.4_r1/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java#380
380 public String findLibrary(String libraryName) {
381 String fileName = System.mapLibraryName(libraryName);
382 for (File directory : nativeLibraryDirectories) {
383 String path = new File(directory, fileName).getPath();
384 if (IoUtils.canOpenReadOnly(path)) {
385 return path;
386 }
387 }
388 return null;
389 }
就是将nativeLibraryDirectories变量遍历里面是否包含了要加载的so文件。
来看下nativeLibraryDirectories是怎么得到的。
/** List of native library directories. */
private final File[]nativeLibraryDirectories;
是一个File[]数组呢,而且是final的。
但是接着看的话,在DexPathList初始化的时候将这个变量进行赋值:
- this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
5.0版本
源码:
http://androidxref.com/5.0.0_r2/xref/libcore/luni/src/main/java/java/lang/Runtime.java
358 void loadLibrary(String libraryName, ClassLoader loader) {
359 if (loader != null) {
360 String filename = loader.findLibrary(libraryName);
361 if (filename == null) {
362 // It's not necessarily true that the ClassLoader used
363 // System.mapLibraryName, but the default setup does, and it's
364 // misleading to say we didn't find "libMyLibrary.so" when we
365 // actually searched for "liblibMyLibrary.so.so".
366 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
367 System.mapLibraryName(libraryName) + "\\"");
368 }
369 String error = doLoad(filename, loader);
370 if (error != null) {
371 throw new UnsatisfiedLinkError(error);
372 }
373 return;
374 }
375
376 String filename = System.mapLibraryName(libraryName);
377 List<String> candidates = new ArrayList<String>();
378 String lastError = null;
379 for (String directory : mLibPaths) {
380 String candidate = directory + filename;
381 candidates.add(candidate);
382
383 if (IoUtils.canOpenReadOnly(candidate)) {
384 String error = doLoad(candidate, loader);
385 if (error == null) {
386 return; // We successfully loaded the library. Job done.
387 }
388 lastError = error;
389 }
390 }
391
392 if (lastError != null) {
393 throw new UnsatisfiedLinkError(lastError);
394 }
395 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
396 }
findLibrary:
379 public String findLibrary(String libraryName) {
380 String fileName = System.mapLibraryName(libraryName);
381 for (File directory : nativeLibraryDirectories) {
382 String path = new File(directory, fileName).getPath();
383 if (IoUtils.canOpenReadOnly(path)) {
384 return path;
385 }
386 }
387 return null;
388 }
nativeLibraryDirectories:
/** List of native library directories. */
private final File[]nativeLibraryDirectories;
也还是File数组且为final。
最后赋值也是跟4.4一样:
- this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
5.1版本
源码:
http://androidxref.com/5.1.1_r6/xref/libcore/luni/src/main/java/java/lang/Runtime.java
358 void loadLibrary(String libraryName, ClassLoader loader) {
359 if (loader != null) {
360 String filename = loader.findLibrary(libraryName);
361 if (filename == null) {
362 // It's not necessarily true that the ClassLoader used
363 // System.mapLibraryName, but the default setup does, and it's
364 // misleading to say we didn't find "libMyLibrary.so" when we
365 // actually searched for "liblibMyLibrary.so.so".
366 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
367 System.mapLibraryName(libraryName) + "\\"");
368 }
369 String error = doLoad(filename, loader);
370 if (error != null) {
371 throw new UnsatisfiedLinkError(error);
372 }
373 return;
374 }
375
376 String filename = System.mapLibraryName(libraryName);
377 List<String> candidates = new ArrayList<String>();
378 String lastError = null;
379 for (String directory : mLibPaths) {
380 String candidate = directory + filename;
381 candidates.add(candidate);
382
383 if (IoUtils.canOpenReadOnly(candidate)) {
384 String error = doLoad(candidate, loader);
385 if (error == null) {
386 return; // We successfully loaded the library. Job done.
387 }
388 lastError = error;
389 }
390 }
391
392 if (lastError != null) {
393 throw new UnsatisfiedLinkError(lastError);
394 }
395 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
396 }
findLibrary:
379 public String findLibrary(String libraryName) {
380 String fileName = System.mapLibraryName(libraryName);
381 for (File directory : nativeLibraryDirectories) {
382 String path = new File(directory, fileName).getPath();
383 if (IoUtils.canOpenReadOnly(path)) {
384 return path;
385 }
386 }
387 return null;
388 }
nativeLibraryDirectories:
/** List of native library directories. */
private final File[] nativeLibraryDirectories;
- this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
- private static File[] splitLibraryPath(String path)
6.0版本
源码:
http://androidxref.com/6.0.1_r10/xref/libcore/luni/src/main/java/java/lang/Runtime.java
359 void loadLibrary(String libraryName, ClassLoader loader) {
360 if (loader != null) {
361 String filename = loader.findLibrary(libraryName);
362 if (filename == null) {
363 // It's not necessarily true that the ClassLoader used
364 // System.mapLibraryName, but the default setup does, and it's
365 // misleading to say we didn't find "libMyLibrary.so" when we
366 // actually searched for "liblibMyLibrary.so.so".
367 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
368 System.mapLibraryName(libraryName) + "\\"");
369 }
370 String error = doLoad(filename, loader);
371 if (error != null) {
372 throw new UnsatisfiedLinkError(error);
373 }
374 return;
375 }
376
377 String filename = System.mapLibraryName(libraryName);
378 List<String> candidates = new ArrayList<String>();
379 String lastError = null;
380 for (String directory : mLibPaths) {
381 String candidate = directory + filename;
382 candidates.add(candidate);
383
384 if (IoUtils.canOpenReadOnly(candidate)) {
385 String error = doLoad(candidate, loader);
386 if (error == null) {
387 return; // We successfully loaded the library. Job done.
388 }
389 lastError = error;
390 }
391 }
392
393 if (lastError != null) {
394 throw new UnsatisfiedLinkError(lastError);
395 }
396 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
397 }
findLibrary:
396 public String findLibrary(String libraryName) {
397 String fileName = System.mapLibraryName(libraryName);
398
399 for (Element element : nativeLibraryPathElements) {
400 String path = element.findNativeLibrary(fileName);
401
402 if (path != null) {
403 return path;
404 }
405 }
406
407 return null;
408 }
nativeLibraryPathElements,从6.0开始好像就有了nativeLibraryPathElements这个属性。
/** List of native library path elements. */
private final Element[] nativeLibraryPathElements;
从这里开始复制
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null,
suppressedExceptions);
然后makePathElements:
private static Element[] makePathElements(List<File>files,File optimizedDirectory,List<IOException>suppressedExceptions)
属性就可以了。
7.0版本
源码:
http://androidxref.com/7.0.0_r1/xref/libcore/ojluni/src/main/java/java/lang/Runtime.java
从7.0开始增加了loadLibrary0这个函数,其实就是将之前的loadLibrary改成了这个,其实都一个作用
959 synchronized void loadLibrary0(ClassLoader loader, String libname) {
960 if (libname.indexOf((int)File.separatorChar) != -1) {
961 throw new UnsatisfiedLinkError(
962 "Directory separator should not appear in library name: " + libname);
963 }
964 String libraryName = libname;
965 if (loader != null) {
966 String filename = loader.findLibrary(libraryName);
967 if (filename == null) {
968 // It's not necessarily true that the ClassLoader used
969 // System.mapLibraryName, but the default setup does, and it's
970 // misleading to say we didn't find "libMyLibrary.so" when we
971 // actually searched for "liblibMyLibrary.so.so".
972 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
973 System.mapLibraryName(libraryName) + "\\"");
974 }
975 String error = doLoad(filename, loader);
976 if (error != null) {
977 throw new UnsatisfiedLinkError(error);
978 }
979 return;
980 }
981
982 String filename = System.mapLibraryName(libraryName);
983 List<String> candidates = new ArrayList<String>();
984 String lastError = null;
985 for (String directory : getLibPaths()) {
986 String candidate = directory + filename;
987 candidates.add(candidate);
988
989 if (IoUtils.canOpenReadOnly(candidate)) {
990 String error = doLoad(candidate, loader);
991 if (error == null) {
992 return; // We successfully loaded the library. Job done.
993 }
994 lastError = error;
995 }
996 }
997
998 if (lastError != null) {
999 throw new UnsatisfiedLinkError(lastError);
1000 }
1001 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
1002 }
findLibrary:
476 public String findLibrary(String libraryName) {
477 String fileName = System.mapLibraryName(libraryName);
478
479 for (Element element : nativeLibraryPathElements) {
480 String path = element.findNativeLibrary(fileName);
481
482 if (path != null) {
483 return path;
484 }
485 }
486
487 return null;
488 }
nativeLibraryPathElements:
/** List of native library path elements. */
private final Element[]nativeLibraryPathElements;
怎么赋值的呢:
145 this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories,
146 suppressedExceptions,
147 definingContext);
又进行了改变
269 private static Element[] makePathElements(List<File> files,
270 List<IOException> suppressedExceptions,
271 ClassLoader loader)
之前6.0的两个list和一个file,又改成了两个list和一个classloader
7.1跟7.0一样不赘述。
8.0
源码:
http://androidxref.com/8.1.0_r33/xref/libcore/ojluni/src/main/java/java/lang/Runtime.java
998 synchronized void loadLibrary0(ClassLoader loader, String libname) {
999 if (libname.indexOf((int)File.separatorChar) != -1) {
1000 throw new UnsatisfiedLinkError(
1001 "Directory separator should not appear in library name: " + libname);
1002 }
1003 String libraryName = libname;
1004 if (loader != null) {
1005 String filename = loader.findLibrary(libraryName);
1006 if (filename == null) {
1007 // It's not necessarily true that the ClassLoader used
1008 // System.mapLibraryName, but the default setup does, and it's
1009 // misleading to say we didn't find "libMyLibrary.so" when we
1010 // actually searched for "liblibMyLibrary.so.so".
1011 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
1012 System.mapLibraryName(libraryName) + "\\"");
1013 }
1014 String error = doLoad(filename, loader);
1015 if (error != null) {
1016 throw new UnsatisfiedLinkError(error);
1017 }
1018 return;
1019 }
1020
1021 String filename = System.mapLibraryName(libraryName);
1022 List<String> candidates = new ArrayList<String>();
1023 String lastError = null;
1024 for (String directory : getLibPaths()) {
1025 String candidate = directory + filename;
1026 candidates.add(candidate);
1027
1028 if (IoUtils.canOpenReadOnly(candidate)) {
1029 String error = doLoad(candidate, loader);
1030 if (error == null) {
1031 return; // We successfully loaded the library. Job done.
1032 }
1033 lastError = error;
1034 }
1035 }
1036
1037 if (lastError != null) {
1038 throw new UnsatisfiedLinkError(lastError);
1039 }
1040 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
1041 }
findLibrary:
524 public String findLibrary(String libraryName) {
525 String fileName = System.mapLibraryName(libraryName);
526
527 for (NativeLibraryElement element : nativeLibraryPathElements) {
528 String path = element.findNativeLibrary(fileName);
529
530 if (path != null) {
531 return path;
532 }
533 }
534
535 return null;
536 }
怎么赋值的呢
- this.nativeLibraryPathElements = makePathElements(this.systemNativeLibraryDirectories);
然后makePathElements:
- private static NativeLibraryElement[] makePathElements(List files)
返回值改了,参数也改了。
就很纳闷,google这帮人不干实事整天改这个干嘛,有漏洞?
总结
4.4 ~5.1
都是使用的
this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
private static File[] splitLibraryPath(String path)
private static File[] splitLibraryPath(String path)
6.0
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null,suppressedExceptions);
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null,suppressedExceptions);
private static Element[] makePathElements(List[File](%5BFile%5D(http://androidxref.com/6.0.1_r10/s?defs=File&project=libcore)) files, File optimizedDirectory,List[IOException](%5BIOException%5D(http://androidxref.com/6.0.1_r10/s?defs=IOException&project=libcore)) suppressedExceptions)
private static Element[] makePathElements(List[File](%5BFile%5D(http://androidxref.com/6.0.1_r10/s?defs=File&project=libcore)) files, File optimizedDirectory,List[IOException](%5BIOException%5D(http://androidxref.com/6.0.1_r10/s?defs=IOException&project=libcore)) suppressedExceptions)
7.0 ~ 7.1
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, suppressedExceptions, definingContext);
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, suppressedExceptions, definingContext);
private static Element[] makePathElements(List files, List suppressedExceptions, ClassLoader loader)
private static Element[] makePathElements(List files, List suppressedExceptions, ClassLoader loader)
8.0 ~ 8.1
this.nativeLibraryPathElements = makePathElements(this.systemNativeLibraryDirectories);
this.nativeLibraryPathElements = makePathElements(this.systemNativeLibraryDirectories);
private static NativeLibraryElement[] makePathElements(List files)
private static NativeLibraryElement[] makePathElements(List files)
Loadlibrary is mainly used in runtime Implemented in Java, there are great differences between different versions, so take a note to sort out these differences.
Version 4.4
Source code:
Cross Reference: /libcore/luni/src/main/java/java/lang/Runtime.java
Mainly this one:
http://androidxref.com/4.4.4_r1/xref/libcore/luni/src/main/java/java/lang/Runtime.java#354
void loadLibrary(String libraryName, ClassLoader loader) {
355 if (loader != null) {
356 String filename = loader.findLibrary(libraryName);
357 if (filename == null) {
358 throw new UnsatisfiedLinkError("Couldn't load " + libraryName +
359 " from loader " + loader +
360 ": findLibrary returned null");
361 }
362 String error = doLoad(filename, loader);
363 if (error != null) {
364 throw new UnsatisfiedLinkError(error);
365 }
366 return;
367 }
368
369 String filename = System.mapLibraryName(libraryName);
370 List<String> candidates = new ArrayList<String>();
371 String lastError = null;
372 for (String directory : mLibPaths) {
373 String candidate = directory + filename;
374 candidates.add(candidate);
375
376 if (IoUtils.canOpenReadOnly(candidate)) {
377 String error = doLoad(candidate, loader);
378 if (error == null) {
379 return; // We successfully loaded the library. Job done.
380 }
381 lastError = error;
382 }
383 }
384
385 if (lastError != null) {
386 throw new UnsatisfiedLinkError(lastError);
387 }
388 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
389 }
A key part of the code is this:
String filename = loader.findLibrary(libraryName);
357 if (filename == null) {
358 throw new UnsatisfiedLinkError("Couldn't load " + libraryName +
359 " from loader " + loader +
360 ": findLibrary returned null");
361 }
Then look for findlibrary.
http://androidxref.com/4.4.4_r1/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java#380
380 public String findLibrary(String libraryName) {
381 String fileName = System.mapLibraryName(libraryName);
382 for (File directory : nativeLibraryDirectories) {
383 String path = new File(directory, fileName).getPath();
384 if (IoUtils.canOpenReadOnly(path)) {
385 return path;
386 }
387 }
388 return null;
389 }
This is to traverse the nativelibrarydirectories variable to see if it contains the so file to be loaded.
Let’s see how native library directories are obtained.
/** List of native library directories. */
private final File[]nativeLibraryDirectories;
It’s a file [] array, and it’s final.
But then, when dexpathlist is initialized, assign this variable:
- this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
Version 5.0
Source code:
http://androidxref.com/5.0.0_r2/xref/libcore/luni/src/main/java/java/lang/Runtime.java
358 void loadLibrary(String libraryName, ClassLoader loader) {
359 if (loader != null) {
360 String filename = loader.findLibrary(libraryName);
361 if (filename == null) {
362 // It's not necessarily true that the ClassLoader used
363 // System.mapLibraryName, but the default setup does, and it's
364 // misleading to say we didn't find "libMyLibrary.so" when we
365 // actually searched for "liblibMyLibrary.so.so".
366 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
367 System.mapLibraryName(libraryName) + "\\"");
368 }
369 String error = doLoad(filename, loader);
370 if (error != null) {
371 throw new UnsatisfiedLinkError(error);
372 }
373 return;
374 }
375
376 String filename = System.mapLibraryName(libraryName);
377 List<String> candidates = new ArrayList<String>();
378 String lastError = null;
379 for (String directory : mLibPaths) {
380 String candidate = directory + filename;
381 candidates.add(candidate);
382
383 if (IoUtils.canOpenReadOnly(candidate)) {
384 String error = doLoad(candidate, loader);
385 if (error == null) {
386 return; // We successfully loaded the library. Job done.
387 }
388 lastError = error;
389 }
390 }
391
392 if (lastError != null) {
393 throw new UnsatisfiedLinkError(lastError);
394 }
395 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
396 }
findLibrary:
379 public String findLibrary(String libraryName) {
380 String fileName = System.mapLibraryName(libraryName);
381 for (File directory : nativeLibraryDirectories) {
382 String path = new File(directory, fileName).getPath();
383 if (IoUtils.canOpenReadOnly(path)) {
384 return path;
385 }
386 }
387 return null;
388 }
nativeLibraryDirectories:
/** List of native library directories. */
private final File[]nativeLibraryDirectories;
It is also a file array and is final.
The final assignment is the same as 4.4:
- this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
Version 5.1
Source code:
http://androidxref.com/5.1.1_r6/xref/libcore/luni/src/main/java/java/lang/Runtime.java
358 void loadLibrary(String libraryName, ClassLoader loader) {
359 if (loader != null) {
360 String filename = loader.findLibrary(libraryName);
361 if (filename == null) {
362 // It's not necessarily true that the ClassLoader used
363 // System.mapLibraryName, but the default setup does, and it's
364 // misleading to say we didn't find "libMyLibrary.so" when we
365 // actually searched for "liblibMyLibrary.so.so".
366 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
367 System.mapLibraryName(libraryName) + "\\"");
368 }
369 String error = doLoad(filename, loader);
370 if (error != null) {
371 throw new UnsatisfiedLinkError(error);
372 }
373 return;
374 }
375
376 String filename = System.mapLibraryName(libraryName);
377 List<String> candidates = new ArrayList<String>();
378 String lastError = null;
379 for (String directory : mLibPaths) {
380 String candidate = directory + filename;
381 candidates.add(candidate);
382
383 if (IoUtils.canOpenReadOnly(candidate)) {
384 String error = doLoad(candidate, loader);
385 if (error == null) {
386 return; // We successfully loaded the library. Job done.
387 }
388 lastError = error;
389 }
390 }
391
392 if (lastError != null) {
393 throw new UnsatisfiedLinkError(lastError);
394 }
395 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
396 }
findLibrary:
379 public String findLibrary(String libraryName) {
380 String fileName = System.mapLibraryName(libraryName);
381 for (File directory : nativeLibraryDirectories) {
382 String path = new File(directory, fileName).getPath();
383 if (IoUtils.canOpenReadOnly(path)) {
384 return path;
385 }
386 }
387 return null;
388 }
nativeLibraryDirectories:
/** List of native library directories. */
private final File[] nativeLibraryDirectories;
- this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
- private static File[] splitLibraryPath(String path)
Version 6.0
Source code:
http://androidxref.com/6.0.1_r10/xref/libcore/luni/src/main/java/java/lang/Runtime.java
359 void loadLibrary(String libraryName, ClassLoader loader) {
360 if (loader != null) {
361 String filename = loader.findLibrary(libraryName);
362 if (filename == null) {
363 // It's not necessarily true that the ClassLoader used
364 // System.mapLibraryName, but the default setup does, and it's
365 // misleading to say we didn't find "libMyLibrary.so" when we
366 // actually searched for "liblibMyLibrary.so.so".
367 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
368 System.mapLibraryName(libraryName) + "\\"");
369 }
370 String error = doLoad(filename, loader);
371 if (error != null) {
372 throw new UnsatisfiedLinkError(error);
373 }
374 return;
375 }
376
377 String filename = System.mapLibraryName(libraryName);
378 List<String> candidates = new ArrayList<String>();
379 String lastError = null;
380 for (String directory : mLibPaths) {
381 String candidate = directory + filename;
382 candidates.add(candidate);
383
384 if (IoUtils.canOpenReadOnly(candidate)) {
385 String error = doLoad(candidate, loader);
386 if (error == null) {
387 return; // We successfully loaded the library. Job done.
388 }
389 lastError = error;
390 }
391 }
392
393 if (lastError != null) {
394 throw new UnsatisfiedLinkError(lastError);
395 }
396 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
397 }
findLibrary:
396 public String findLibrary(String libraryName) {
397 String fileName = System.mapLibraryName(libraryName);
398
399 for (Element element : nativeLibraryPathElements) {
400 String path = element.findNativeLibrary(fileName);
401
402 if (path != null) {
403 return path;
404 }
405 }
406
407 return null;
408 }
nativeLibraryPathElements,从6.0开始好像就有了nativeLibraryPathElements这个属性。
/** List of native library path elements. */
private final Element[] nativeLibraryPathElements;
Copy from here
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null,
suppressedExceptions);
然后makePathElements:
private static Element[] makePathElements(List<File>files,File optimizedDirectory,List<IOException>suppressedExceptions)
Property is OK.
Version 7.0
Source code:
http://androidxref.com/7.0.0_r1/xref/libcore/ojluni/src/main/java/java/lang/Runtime.java
The function loadlibrary0 has been added since 7.0. In fact, it changes the previous loadlibrary to this function. In fact, it has one function
959 synchronized void loadLibrary0(ClassLoader loader, String libname) {
960 if (libname.indexOf((int)File.separatorChar) != -1) {
961 throw new UnsatisfiedLinkError(
962 "Directory separator should not appear in library name: " + libname);
963 }
964 String libraryName = libname;
965 if (loader != null) {
966 String filename = loader.findLibrary(libraryName);
967 if (filename == null) {
968 // It's not necessarily true that the ClassLoader used
969 // System.mapLibraryName, but the default setup does, and it's
970 // misleading to say we didn't find "libMyLibrary.so" when we
971 // actually searched for "liblibMyLibrary.so.so".
972 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
973 System.mapLibraryName(libraryName) + "\\"");
974 }
975 String error = doLoad(filename, loader);
976 if (error != null) {
977 throw new UnsatisfiedLinkError(error);
978 }
979 return;
980 }
981
982 String filename = System.mapLibraryName(libraryName);
983 List<String> candidates = new ArrayList<String>();
984 String lastError = null;
985 for (String directory : getLibPaths()) {
986 String candidate = directory + filename;
987 candidates.add(candidate);
988
989 if (IoUtils.canOpenReadOnly(candidate)) {
990 String error = doLoad(candidate, loader);
991 if (error == null) {
992 return; // We successfully loaded the library. Job done.
993 }
994 lastError = error;
995 }
996 }
997
998 if (lastError != null) {
999 throw new UnsatisfiedLinkError(lastError);
1000 }
1001 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
1002 }
findLibrary:
476 public String findLibrary(String libraryName) {
477 String fileName = System.mapLibraryName(libraryName);
478
479 for (Element element : nativeLibraryPathElements) {
480 String path = element.findNativeLibrary(fileName);
481
482 if (path != null) {
483 return path;
484 }
485 }
486
487 return null;
488 }
nativeLibraryPathElements:
/** List of native library path elements. */
private final Element[]nativeLibraryPathElements;
How to assign values:
145 this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories,
146 suppressedExceptions,
147 definingContext);
Changed again
269 private static Element[] makePathElements(List<File> files,
270 List<IOException> suppressedExceptions,
271 ClassLoader loader)
The two lists and a file in 6.0 have been changed to two lists and a classloader
7.1 is the same as 7.0 and will not be repeated.
eight
Source code:
http://androidxref.com/8.1.0_r33/xref/libcore/ojluni/src/main/java/java/lang/Runtime.java
998 synchronized void loadLibrary0(ClassLoader loader, String libname) {
999 if (libname.indexOf((int)File.separatorChar) != -1) {
1000 throw new UnsatisfiedLinkError(
1001 "Directory separator should not appear in library name: " + libname);
1002 }
1003 String libraryName = libname;
1004 if (loader != null) {
1005 String filename = loader.findLibrary(libraryName);
1006 if (filename == null) {
1007 // It's not necessarily true that the ClassLoader used
1008 // System.mapLibraryName, but the default setup does, and it's
1009 // misleading to say we didn't find "libMyLibrary.so" when we
1010 // actually searched for "liblibMyLibrary.so.so".
1011 throw new UnsatisfiedLinkError(loader + " couldn't find \\"" +
1012 System.mapLibraryName(libraryName) + "\\"");
1013 }
1014 String error = doLoad(filename, loader);
1015 if (error != null) {
1016 throw new UnsatisfiedLinkError(error);
1017 }
1018 return;
1019 }
1020
1021 String filename = System.mapLibraryName(libraryName);
1022 List<String> candidates = new ArrayList<String>();
1023 String lastError = null;
1024 for (String directory : getLibPaths()) {
1025 String candidate = directory + filename;
1026 candidates.add(candidate);
1027
1028 if (IoUtils.canOpenReadOnly(candidate)) {
1029 String error = doLoad(candidate, loader);
1030 if (error == null) {
1031 return; // We successfully loaded the library. Job done.
1032 }
1033 lastError = error;
1034 }
1035 }
1036
1037 if (lastError != null) {
1038 throw new UnsatisfiedLinkError(lastError);
1039 }
1040 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates);
1041 }
findLibrary:
524 public String findLibrary(String libraryName) {
525 String fileName = System.mapLibraryName(libraryName);
526
527 for (NativeLibraryElement element : nativeLibraryPathElements) {
528 String path = element.findNativeLibrary(fileName);
529
530 if (path != null) {
531 return path;
532 }
533 }
534
535 return null;
536 }
How do you assign values
- this.nativeLibraryPathElements = makePathElements(this.systemNativeLibraryDirectories);
然后makePathElements:
- private static NativeLibraryElement[] makePathElements(List files)
The return value and parameters have been changed.
I wonder why Google people do nothing to change this all day. Is there a loophole?
summary
4.4 ~5.1
Are used
this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
this.nativeLibraryDirectories = splitLibraryPath(libraryPath);
private static File[] splitLibraryPath(String path)
private static File[] splitLibraryPath(String path)
six
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null,suppressedExceptions);
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, null,suppressedExceptions);
private static Element[] makePathElements(List[File](%5BFile%5D(http://androidxref.com/6.0.1_r10/s?defs=File&project=libcore)) files, File optimizedDirectory,List[IOException](%5BIOException%5D(http://androidxref.com/6.0.1_r10/s?defs=IOException&project=libcore)) suppressedExceptions)
private static Element[] makePathElements(List[File](%5BFile%5D(http://androidxref.com/6.0.1_r10/s?defs=File&project=libcore)) files, File optimizedDirectory,List[IOException](%5BIOException%5D(http://androidxref.com/6.0.1_r10/s?defs=IOException&project=libcore)) suppressedExceptions)
7.0 ~ 7.1
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, suppressedExceptions, definingContext);
this.nativeLibraryPathElements = makePathElements(allNativeLibraryDirectories, suppressedExceptions, definingContext);
private static Element[] makePathElements(List files, List suppressedExceptions, ClassLoader loader)
private static Element[] makePathElements(List files, List suppressedExceptions, ClassLoader loader)
8.0 ~ 8.1
this.nativeLibraryPathElements = makePathElements(this.systemNativeLibraryDirectories);
this.nativeLibraryPathElements = makePathElements(this.systemNativeLibraryDirectories);
private static NativeLibraryElement[] makePathElements(List files)
private static NativeLibraryElement[] makePathElements(List files)