Dalvik virtual machine dynamic load Dex/jar

Source: Internet
Author: User
Tags file copy

Guo Xiaoxing
Weibo: Guo Xiaoxing's Sina Weibo
Email:[email protected]
Blog: http://blog.csdn.net/allenwells
Github:https://github.com/allenwell

In the article Dalvik the mechanism of virtual machine load class, we discuss the principle of Dalvik virtual machine load class, this article discusses how to use these mechanisms provided by Dalvik for dynamic loading of Dex/jar.

The first thing to note is that while the Dalvik virtual machine can be dynamically loaded, it is not as easy as a Java virtual machine to load the jar dynamically, nor does it support loading class files from a byte stream.

The reason for this is that the Dalvik virtual machine runs not the class bytecode in the Java packaged jar, but rather optimizes the converted Dalvik bytecode with the DX tool. In the Android Project package apk, the introduced Jar will also be packaged into the classes.dex.

Here's an example of how to invoke Dex/jar dynamically.

(1) Write the interface class
package com.allenwells.dexdynamiccalldemo;import android.content.Context;publicinterface LibraryInterface{    publicvoidshowAwesomeToast(Context context, String message);}
(2) Implement the interface class
 PackageCom.allenwells.dexdynamiccalldemo.lib;ImportCom.allenwells.dexdynamiccalldemo.LibraryInterface;ImportAndroid.content.Context;ImportAndroid.widget.Toast; Public  class libraryprovider implements libraryinterface{     Public void Showawesometoast(Context context, String message) {if(Context = =NULL)        {return; } toast.maketext (Context, String.Format ("Libraryprovider Print: + +%s + +", message), Toast.length_long). Show (); }}
(3) Packaging the interface implementation class Libraryprovider into a jar file

After packaging as shown:

At this point the jar contains the JVM bytecode, which can only be recognized by the Java Virtual machine.

(4) Convert class file to Dex file

The DX tool is under android_sdk_home\build-tools\android-4.3, so skip the command line to the current directory, copy the Jvmcode.jar to the directory, and execute the following command:

dx--dex--output==DalvikCode.jarJVMCode.jar

After the command executes, the Dalvikcode.jar file is generated in the current directory, although Dalvikcode.jar is the file name suffix of the. jar, but it contains the Dex file, as shown in:

Put the generated dalvikcode.jar into the project's assets folder and delete the Com.allenwells.dexdynamiccalldemo.lib package, as shown in:

(5) Implement mainactivity, make external dex dynamic call.
 PackageCom.allenwells.dexdynamiccalldemo;ImportJava.io.BufferedInputStream;ImportJava.io.BufferedOutputStream;ImportJava.io.File;ImportJava.io.FileOutputStream;ImportJava.io.IOException;ImportJava.io.OutputStream;Importandroid.app.Activity;ImportAndroid.app.ProgressDialog;ImportAndroid.content.Context;ImportAndroid.os.AsyncTask;ImportAndroid.os.Bundle;ImportAndroid.view.View;ImportAndroid.widget.ImageButton;ImportDalvik.system.dexclassloader;public class mainactivity extends Activity {PrivateStaticFinalString Secondary_dex_name ="Dalvikcode.jar";/ * * Set the copy cache size, this example uses 8*1024, or you can set the cache based on the actual size of the Secondary_dex.jar */    PrivateStaticFinalint buf_size =8*1024x768;PrivateImageButton Mtoastbutton =NULL;PrivateProgressDialog Mprogressdialog =NULL;@Overridepublic void OnCreate (Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);        Setcontentview (R.layout.activity_main); Mtoastbutton = (ImageButton) Findviewbyid (R.id.toast_button);/ * Copy the Secondary_dex.jar from the Aeest resource to the store for Dexclassloader calls * /        FinalFile Dexinternalstoragepath =NewFile (Getdir ("Dex", context.mode_private), secondary_dex_name);if(!dexinternalstoragepath.exists ()) {Mprogressdialog = Progressdialog.show ( This, Getresources (). getString (R.string.diag_title), Getresources (). getString (r.string. Diag_message),true,false);/ * File copy in asynchronous task * /(NewPreparedextask ()). Execute (Dexinternalstoragepath); }Else{mtoastbutton.setenabled (true); } mtoastbutton.setonclicklistener (NewView.onclicklistener () {public void OnClick (view view) {/ * Dexclassloader The internal path that will be written to the optimized Dex file * /                FinalFile Optimizeddexoutputpath = Getdir ("Outdex", context.mode_private);/ * Initialize Dexclassloader with third-party DEX files * /Dexclassloader Dexclassloader =NewDexclassloader (Dexinternalstoragepath.getabsolutepath (), Optimizeddexoutput Path.getabsolutepath (),NULL, getClassLoader ()); Class<?> Libproviderclazz =NULL;Try{/ * Load Libraryprovider class with class loader * /Libproviderclazz = Dexclassloader. LoadClass ("Com.allenwells.dexdynamiccalldemo.lib.LibraryProvider");/ * * Converts the returned object to a type, making it possible to make method calls directly in the interface.                     Another way to call it is to call with reflection, but this is a complex and inefficient operation. */Libraryinterface lib = (libraryinterface) libproviderclazz. newinstance ();/ * Call method, output print * /Lib.showawesometoast (View.getcontext (),"Hello"); }Catch(Exception Exception)                {Exception.printstacktrace ();    }            }        }); }/ * Copy the third-party Dex file from the asset resource file to the memory store * /    PrivateBoolean Preparedex (File dexinternalstoragepath) {Bufferedinputstream bis =NULL; OutputStream Dexwriter =NULL;Try{bis =NewBufferedinputstream (Getassets (). Open (Secondary_dex_name)); Dexwriter =NewBufferedoutputstream (NewFileOutputStream (Dexinternalstoragepath)); byte[] buf =NewByte[buf_size]; int Len; while(len = Bis.read (buf,0, buf_size)) >0) {Dexwriter.write (buf,0, Len);            } dexwriter.close (); Bis.close ();return true; }Catch(IOException e) {if(Dexwriter! =NULL)            {Try{Dexwriter.close (); }Catch(IOException IoE)                {Ioe.printstacktrace (); }            }if(bis! =NULL)            {Try{Bis.close (); }Catch(IOException IoE)                {Ioe.printstacktrace (); }            }return false; }    }Private  class preparedextask extends asynctask<File, Void, Boolean>{@Override        protectedvoid oncancelled () {Super. oncancelled ();if(Mprogressdialog! =NULL) Mprogressdialog.cancel (); }@Override        protectedvoid OnPostExecute (Boolean result) {Super. OnPostExecute (Result);if(Mprogressdialog! =NULL) Mprogressdialog.cancel (); }@Override        protectedBoolean doinbackground (File ... dexinternalstoragepaths) {Preparedex (dexinternalstoragepaths[0]);return NULL; }    }}

Click Ddms to view the file information for the app under File Explorer, and you can see that Dalvikcode.jar is saved in the internal storage as shown in:

All work done from this, click on the Test button, run the program, as shown in the effect:

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Dalvik virtual machine dynamic load Dex/jar

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.