Android Code Hot fix Detailed

Source: Internet
Author: User

Java: Class loading principle:
When the ClassLoader receives a request to load a class or resource, it is usually the first delegate to the parent ClassLoader to load, that is, the actual class loading process is performed only when the parent ClassLoader cannot find the specified class or resource, and the loading process is as follows:

1, the source ClassLoader first to determine whether the class has been loaded, if loaded, then directly return to the class, if not, delegate to the parent class loader.

2, the parent class loader determines whether the class is loaded, if it is loaded, returns the class directly, if not, delegate to the Grandfather class loader.

3, and so on, until the Ancestor class loader (reference ClassLoader).

4, the Ancestor class loader to determine whether the class has been loaded, if loaded, then directly return to the class, if not, try to find the class bytecode file and load it from its corresponding classpath. If the load succeeds, the class is returned directly, and if loading fails, the subclass loader is delegated to the ancestor ClassLoader.
5. The subclass loader of the ancestor ClassLoader tries to find the class bytecode file and load it from its corresponding classpath. If the load succeeds, the class is returned directly, and if the load fails, it is delegated to the ancestor ClassLoader's grandchild class loader.

6, and so on, until the source ClassLoader.

7. The source ClassLoader attempts to find the class bytecode file and load it from its corresponding classpath. If the load succeeds, the class is returned directly, and if the load fails, the source ClassLoader no longer delegates its child classloader, but throws an exception

Android class loading:
The class loader in Android is Bootclassloader, Pathclassloader, Dexclassloader, where Bootclassloader is required for the virtual machine load system class, Pathclassloader is used by the app to load classes in its own Dex file, and Dexclassloader can load files that contain DEX files directly or indirectly.

Pathclassloader and Dexclassloader are inherited from Basedexclassloader, and it is important to have a dexpathlist type of member variable pathlist. There is an array of element types in Dexpathlist dexelements, which holds elements containing the Dex file (corresponding to Dexfile). Basedexclassloader loads a class and finally calls the Dexfile method to load the

Here are two ways to code hot FIX:
1, according to the class loading as the parent delegate loading principle will load the repaired Dex's dexclassloader into the middle of pathclassloader and Bootstrapclassloader, That is, the Dexclassloader is set to Pathclassloader's parent loader, Bootstrapclassloader is set to Dexclassloader order: Bootstrapclassloader--- >dexclassloader--->pathclassloader

Replacing a bug with a class loaded as a parent delegate loading principle puts the Dexclassloader priority load/class loading order in Dexpath: bootstrapclassloader---->dexclassloader----- >pathclassloader public void Loadpatchdex (context context, string Dexpath, String optimizeddirectory, String library SearchPath) {ClassLoader Currentclassloader = Context.getclassloader ();//context loader (Pathclassloader) Classl        Oader Parentclassloader = Currentclassloader.getparent ()//context parent loader (bootstrapclassloader)//Load Dexpath Loader Dexclassloader Dexclassloader = new Dexclassloader (Dexpath, Optimizeddirectory, Librarysearchpath, ParentClassLoader)        ; This.setfield (Classloader.class, This.mparentfieldname, Currentclassloader, dexclassloader);//  Sets the current class loader's parent loader to Dexclassloader}/** * @param clazz * @param fieldName property name * @param target object to set properties for * The value of the @param value setting property * @return Set successfully */private Boolean SetField (Class clazz, String fieldName, Object targe T, Object value) {try {field field= Clazz.getdeclaredfield (FieldName);                if (field! = null) {field.setaccessible (true);            Field.set (target, value);        } return true;        } catch (Nosuchfieldexception e) {e.printstacktrace ();        } catch (Illegalaccessexception e) {e.printstacktrace (); } Return false;//Setup failed}

2, according to the Android Pathclassloader loading mechanism will dexclassloader load the new Dex added dexpathlist dexelements attribute list, Put the updated Dex load before the Dexelements list index

     public void LoadPatchDex2 (context context, string Dexpath, String optimizeddirectory, String librarysearchpath) {        ClassLoader Pathclassloader = Context.getclassloader (); Load Dexpath loader Dexclassloader dexclassloader = new Dexclassloader (Dexpath, Optimizeddirectory, Librarysearchpath, p        Athclassloader.getparent ());  Gets the Dexpathlist property of the Basedexclassloader private that needs to be obtained by reflection of Object DexPathList1 = This.getfieldvalue (Basedexclassloader.class, This.mdexpathlistfieldname, Pathclassloader);//pathclassloader's PathList property Object dexPathList2 = This.getfieldvalue        (Basedexclassloader.class, This.mdexpathlistfieldname, Dexclassloader); if (dexPathList1! = NULL && DEXPATHLIST2! = null) {//Gets the dexelements attribute in the corresponding pathlist Object dex Elements1 = This.getfieldvalue (Dexpathlist1.getclass (), This.melementfieldname, dexPathList1);// Element[in current Pathclassloader] Property Object dexElements2 = This.getfieldvalue (Dexpathlist2.getclass (), this. Melementfieldname, DexPathList2);//dexclassloader in element[] property if (dexElements1! = null && dexelements 2! = null) {//two element[] properties are merged with Object finalelements = Combinearray (dexElements2, dexelement                S1); Set the merged value to the current pathclassloader of element[] This.setfield (Dexpathlist1.getclass (), This.melementfieldname, DexP                AthList1, finalelements);            LOG.E ("Hotfixengine", "loadpatchdex2:success"); }}}/** * Gets the corresponding property value * @param clazz * @param fieldName property name * @param target object to manipulate * @retu RN */Private Object GetFieldValue (Class clazz, String fieldName, Object target) {Field field = This.getfie        LD (Clazz, fieldName);                if (field! = null) {try {field.setaccessible (true);            return Field.get (target);            } catch (Illegalaccessexception e) {e.printstacktrace (); }} return Null } private Field GetField (Class clazz, String fieldName) {try {Field field = Clazz.getdeclaredfield (            FieldName);            Field.setaccessible (TRUE);        return field;        } catch (Nosuchfieldexception e) {e.printstacktrace ();    } return null; }/** * Two number combinations and * * @param ARRAYLHS * @param arrayrhs * @return * */private static Object Comb        Inearray (Object arraylhs, Object arrayrhs) {class<?> localclass = Arraylhs.getclass (). Getcomponenttype ();        int i = array.getlength (ARRAYLHS);        Int J = i + array.getlength (ARRAYRHS);        Object result = Array.newinstance (Localclass, J);            for (int k = 0; k < J; ++k) {if (K < i) {Array.set (result, K, Array.get (ARRAYLHS, k));            } else {Array.set (result, K, Array.get (ARRAYRHS, k-i));    }} return result; }

Demo Address: Https://github.com/xuguohongai/android/tree/master/AndroidHotFixDemo

Android Code Hot fix Detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.