Http://www.jianshu.com/p/f751be55d1fb
words 549 Read 177 Comments 0 likes 0
- The requirement is simple to load. So in the specified folder.
- Cause: Android cannot write files under Data/data/packagename/lib while the program is running, but it is readable.
- There is also an extended question:What is the relationship between. So and Data/data/packagename/lib. so in data/app-lib/packagename/?
1. Get the global ClassLoader
new DexClassLoader(str, context.getDir("dex", 0).getAbsolutePath(), str, context.getClassLoader().getParent());
2. Get PathList
Object pathList = getPathList(pathClassLoader);
3. Add path
new File[]{new File("/data/app-lib/pakageName-1"),new File("/data/app-lib/pakageName-2"),new File("/data/data/pakageName/files"),new File("/vendor/lib"),new File("/system/lib")} ;
4. Gets the properties of the current class
Object nativeLibraryDirectories=pathList.getClass().getDeclaredField("nativeLibraryDirectories");((Field)nativeLibraryDirectories).setAccessible(true);
5. Set a new path
((Field)nativeLibraryDirectories).set(pathList, file);
6. Operation on ClassLoader, corresponding to Basedexclassloader:
public BaseDexClassLoader(String dexPath,File optimizedDirectory,String libraryPath,ClassLoader parent){ super(parent); this.pathList=new DexPathList(this,dexPath,libraryPath,optimizedDirectory);}
7. The dex,library path corresponds to Dexpathlist, which is closely related to hot patches and is interested in searching hotfix, many open source projects.
privatefinalElement[]dexElements; //这部分就是dex分包的了,热补丁,热补丁,热补丁privatefinalFile[]nativeLibraryDirectories;//这部分就是 libs 加载路径了,默认有 /vendor/lib system/lib data/app-lib/packageName
Finally, give the following code:
PublicStaticvoidInitnativedirectory(Application application) {if (Hasdexclassloader ()) {try {createnewnativedir (application);}catch (Exception e) {e.printstacktrace ();}} }PrivateStaticvoidCreatenewnativedir(Context context)Throws exception{Pathclassloader Pathclassloader = (pathclassloader) context.getclassloader (); Object pathList = getpathlist (Pathclassloader);Gets the properties of the current class Object nativelibrarydirectories = Pathlist.getclass (). Getdeclaredfield ("Nativelibrarydirectories"); (Field) nativelibrarydirectories). Setaccessible (true);Gets the property value in Dexpathlist file[] files1 = (file[]) (Field) nativelibrarydirectories). Get (PathList); Object filesss = array.newinstance (File.class, Files1.length +1);Add Custom. So path Array.set (Filesss,0,New File (Context.getfilesdir (). GetAbsolutePath ()));Put the system on its own appendForint i =1;i<files1.length+1;i++) {Array.set (filesss,i,files1[i-1]); }file[] filesss = new file[file.length+ files1.length];Filesss[0] = file[0];for (int i = 1;i < files1.length+1;i++) {Filesss[i] = Files1[i];} (Field) nativelibrarydirectories). Set (PathList, filesss); }PrivateStatic ObjectGetpathlist(Object obj)Throws ClassNotFoundException, Nosuchfieldexception, illegalaccessexception {return GetField (obj, Class.forName ("Dalvik.system.BaseDexClassLoader"),"PathList"); }PrivateStatic ObjectGetField(Object obj, Class cls, String str)throws Nosuchfieldexception, illegalaccessexception {Field Declaredfield = Cls.getdeclaredfield (str); Declaredfield.setaccessible (true); return Declaredfield.get (obj); /** * Support only for 4.0 + * @return * /private static boolean Hasdexclassloader() { try {class.f ORName ("Dalvik.system.BaseDexClassLoader"); return true;} catch (ClassNotFoundException var1) { return false;}}
Reference links
Android LoadLibrary Change the libpath path, specify the path to load. So