Android之BaseDexClassLoader如何使用
本篇内容介绍了“Android之BaseDexClassLoader如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
前言
一共有4个参数,分来来讲。
1:dexFile(String类型)
2:optimizedDirectory(File类型)
3:librarySearchPath(String类型)
4:parent(ClassLoader类型)
一.dexPath(String)
官方的注释:
*@paramdexPaththelistofjar/apkfilescontainingclassesand*resources,delimitedby{@codeFile.pathSeparator},which*defaultsto{@code":"}onAndroid.
包含类和类的jar/apk文件列表资源,由{@code File.pathSeparator}分隔,其中Android上的默认值为{@code”:“}。
也就是说这里其实是可以传入一个集合的。
比如如下的参数都是可以被接受的:
sdcard/test/aa.apk
sdcard/test/aa.apk:sdcard/test/bb.apk:sdcard/test/cc.apk
sdcard/test/aa.apk:sdcard/test/dd.jar
其中分隔符:,保险起见,可以使用File.pathSeparator替代。
示例代码如下:
privatevoidloadDex(List<File>apkList){StringBuilderbuilder=newStringBuilder();for(Filef:apkList){builder.append(f.getAbsolutePath());builder.append(File.separatorChar);}DexClassLoaderdexClassLoader=newDexClassLoader(builder.toString(),null,null,getClass().getClassLoader());}
二.optimizedDirectory
官方的注释:
this parameter is deprecated and has no effect since API level 26.
解压的路径,这里传入路径的最主要目的就是为了生成odex文件夹,方便后续存储odex文件。
如注释中所写,这个参数26开始已经失效了。所以这里就不扩展去讲了。
三.librarySearchPath
官方的注释:
* @param librarySearchPath the list of directories containing native
包含native目录的目录列表,这里要注意的,传入的一定是so的上一级目录才可以。如果是更上一层的目录是不行的。前言中的问题就出在这,传入了一个更上一层的目录地址。
排查流程:
最终使用librarySearchPath的地方是在DexPathList的splitPaths方法中。生成File加入List中:
@UnsupportedAppUsageprivatestaticList<File>splitPaths(StringsearchPath,booleandirectoriesOnly){List<File>result=newArrayList<>();if(searchPath!=null){for(Stringpath:searchPath.split(File.pathSeparator)){...result.add(newFile(path));}}returnresult;}
而使用的时候,是使用了findLibrary的方法,for循环便利上面集合中的所有path,看是否存在。
publicStringfindLibrary(StringlibraryName){StringfileName=System.mapLibraryName(libraryName);for(NativeLibraryElementelement:nativeLibraryPathElements){Stringpath=element.findNativeLibrary(fileName);if(path!=null){returnpath;}}returnnull;}
而寻找的最终会调用到NativeLibraryElement的findNativeLibrary方法:
publicStringfindNativeLibrary(Stringname){maybeInit();if(zipDir==null){StringentryPath=newFile(path,name).getPath();if(IoUtils.canOpenReadOnly(entryPath)){returnentryPath;}}elseif(urlHandler!=null){//HavingaurlHandlermeanstheelementhasazipfile.//InthiscaseAndroidsupportsloadingthelibraryiff//itisstoredinthezipupressed.StringentryName=zipDir+'/'+name;if(urlHandler.isEntryStored(entryName)){returnpath.getPath()+zipSeparator+entryName;}}returnnull;}
这段代码也就是问题的核心了,直接使用了new File(path,name)的方式,而不是循环查找,所以只有上一层才可以。
四.parent
官方的注释:
@param parent the parent class loader
这个比较简单,就是上一层的classLoader。
“Android之BaseDexClassLoader如何使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注主机评测网网站,小编将为大家输出更多高质量的实用文章!
上一篇:怎么使用SpringBoot+Vue+Flowable模拟实现请假审批流程
下一篇:JWT登录认证实例分析