Analyze Google's Multidex library

Source: Internet
Author: User

We are in the development of projects, like to introduce a lot of third-party packages, greatly facilitate our development, but at the same time, because the total number of Android methods can not exceed 65k, however, with our development, 65k will eventually exceed, so, Google gives this solution, But has been curious about how it is implemented internally, we come today according to the source code to see what the package did, how to put multiple Dex read out. Let's look at the categories in this package:

We first look at multidexapplication, as long as our own application inherit multidexapplication can solve the problem, then we come to see what it does, there is only one way, Rewritten the Attachbasecontext ().

1 protected void Attachbasecontext (Context base) {2     Super . Attachbasecontext (base); 3     Multidex.install (this); 4 }

We see that the specific implementation is a direct call to the Multidex, and then we look at what's inside the install (the key code):

1      Public Static voidInstall (context context) {2         Try {3               .4               .5               .6                 /*The patched class loader is expected to be a descendant of7 * Dalvik.system.BaseDexClassLoader. We Modify its8 * dalvik.system.DexPathList pathList field to append additional DEX9 * file entries.Ten                  */ One ClassLoader Loader; A                 Try { -Loader =Context.getclassloader (); -}Catch(RuntimeException e) { the                 } -                  -File Dexdir =NewFile (Applicationinfo.datadir, secondary_folder_name); -list<file> files = multidexextractor.load (context, ApplicationInfo, Dexdir,false); +                 if(Checkvalidzipfiles (Files)) { - installsecondarydexes (loader, dexdir, files); +}Else { A                   . at                   . -                   . -                 } -             } -}Catch(Exception e) { -         } in}

With ClassLoader's comments we already know that the path to the main dex file is stored in the pathlist in Basedexclassloader, so it's clear that the next thing to do is to find the other Dex file paths, Add to the pathlist above. The loader in this is an example of Basedexclassloader.

  Line Multidexextractor This class, literally knowing that it is extracting DEX information, the Load method extracts other Dex files (without the main DEX) from the specified path according to the Dex naming convention, which can be implemented by itself, so that All the Times Dex files are extracted and assigned to files

  Line will check if all of the above files are valid Zip files, and if there is a false, the Dex file will be re-extracted

  If there is no problem with the line check, it will be executed installsecondarydexes (), and it is clear what is going to happen next, and let's see what is done in this method.

1     Private Static voidInstallsecondarydexes (ClassLoader loader, File dexdir, list<file>files)2             throwsillegalargumentexception, Illegalaccessexception, Nosuchfieldexception,3 invocationtargetexception, Nosuchmethodexception, IOException {4         if(!Files.isempty ()) {5             if(Build.VERSION.SDK_INT >= 19) {6 v19.install (loader, files, dexdir);7}Else if(Build.VERSION.SDK_INT >= 14) {8 v14.install (loader, files, dexdir);9}Else {Ten v4.install (loader, files); One             } A         } -}

The code is clearly written, so let's take a look at the implementation of V19.

1         Private Static voidInstall (ClassLoader loader, list<file>Additionalclasspathentries,2 File optimizeddirectory)3                         throwsillegalargumentexception, Illegalaccessexception,4 nosuchfieldexception, InvocationTargetException, nosuchmethodexception {5             /*The patched class loader is expected to be a descendant of6 * Dalvik.system.BaseDexClassLoader. We Modify its7 * dalvik.system.DexPathList pathList field to append additional DEX8 * file entries.9              */TenField Pathlistfield = FindField (loader, "PathList"); OneObject dexpathlist =pathlistfield.get (loader); AArraylist<ioexception> suppressedexceptions =NewArraylist<ioexception>(); -Expandfieldarray (Dexpathlist, "dexelements", Makedexelements (Dexpathlist, -                     NewArraylist<file>(additionalclasspathentries), Optimizeddirectory, the suppressedexceptions)); -             . -             . -             . +}

We said before the comments appear again, it appears that the specific implementation of the operation is here, mainly with reflection to modify its value, we mainly look at a few main operating methods:

   There are two ways to take note of Makedexelements () and Expandfieldarray (), first of all, we know that when instantiating Basedexclassloader, The path information of the main Dex is stored in the pathlist, while the other inside the dexpathlist is storing the Dex's path in an element array, so look at makedexelements () and know, this method, The incoming Dex file is assembled by reflection into an element array suitable for dexpathlist internal use.

1         Private Staticobject[] Makedexelements (2Object Dexpathlist, arraylist<file>files, File optimizeddirectory,3Arraylist<ioexception>suppressedexceptions)4                         throwsillegalaccessexception, InvocationTargetException,5 nosuchmethodexception {6Method makedexelements =7FindMethod (Dexpathlist, "makedexelements", ArrayList.class, File.class,8ArrayList.class);9 Ten             return(object[]) Makedexelements.invoke (dexpathlist, files, optimizeddirectory, One suppressedexceptions); A}

Look at it the code is reflected call Dexpathlist inside the makedexelements (), but I have not found this method, do not know the code version of the problem or other reasons, hope to know the great God told. Next we look at Expandfieldarray ()

    Private Static voidExpandfieldarray (Object instance, String fieldName, object[] extraelements)throwsnosuchfieldexception, IllegalArgumentException, illegalaccessexception {Field Jlrfield=FindField (instance, fieldName); Object[] Original=(object[]) Jlrfield.get (instance); Object[] Combined=(object[]) array.newinstance (Original.getclass (). Getcomponenttype (), Original.length+extraelements.length); System.arraycopy (Original,0, combined, 0, original.length); System.arraycopy (Extraelements,0, combined, original.length, extraelements.length);    Jlrfield.set (instance, combined); }

Can be seen, and re-established a element[], the original and new data are put up, and finally assigned to Dexelements. This will allow all of Dex to be read out.

Analyze Google's Multidex library

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.