Reflecting the ClassLoader class loading with class loader (ii)

More Android Video Advanced Architecture Advanced Learning Click: https://space.bilibili.com/474380680
This article from the following elements to illustrate reflection and class loader:

  • [Dynamic proxy mode]
  • [In the Android Dalvik and the ART]
  • [PathClassLoader and DexClassLoader]
  • [Parents delegate mechanism]

A dynamic proxy mode

Dynamic Proxy

The so-called static and dynamic means that invocation interface methods. Static agent, is explicitly real object method calls, and call the real dynamic proxy object is a method by way of reflection.

public class DynamicProxy implements InvocationHandler {
    // 这个就是我们要代理的真实对象
    private Object subject;
 
    // 构造方法,给我们要代理的真实对象赋初值
    public DynamicProxy(Object subject) {
        this.subject = subject;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(subject, args);
    }
}
 
public class ProxyClient {
    public static void main(String[] args) {
        Subject realSubject = new RealSubject();
 
        InvocationHandler handler = new design.pattern.structure.proxy.demo.DynamicProxy(realSubject);
        Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);
        subject.operate1();
        subject.operate2("hello proxy");
    }
}

Three roles: interface class, real object, InvocationHandler implementation class

By a Java method call Proxy.newProxyInstance, Subject to generate an instance of the object; method call interface, passed to the handler, the handler invoke execution by indirectly calling a method of the real object.

Two, Android in Dalvik and ART

2.1 What is Dalvik?

Dalvik is Google's own Android platform designed for virtual machines.
Dalvik virtual machine is the core Google and other vendors to develop the Android mobile device platform, one of the components.
It can support the run has been converted to a format ** ** .dex of Java applications, .dex format is a compression format designed specifically for Dalvik, for memory and processor speed limited system.
Dalvik is optimized to allow multiple virtual machine instances running simultaneously in a limited memory, and each Dalvik application as a separate Linux process execution. Separate process can prevent all programs are closed when the virtual machine crashes.
For a long time, Dalvik virtual machine has been blamed as the source of slow down Android users running slower than the IOS.
June 25, 2014, Android L officially unveiled Google I / O conference to be held, Android L larger amplitude changes, Google will delete Dalvik, instead of it is rumored ART.

2.2 Dalvik JVM and what's the relationship?

The main difference:
the Dalvik is register-based, and the JVM is based on the stack.
Dalvik dex file to run, and run java JVM bytecode
since the beginning of Android 2.2, support Dalvik JIT (just-in-time, real-time compiler technology).
Dalvik optimized some different characteristics than the other virtual machine criteria: 
1. take up less space 
2. In order to simplify the translation, only 32-bit constant pool index  
3. Standard Java byte code instruction stack implementation eight, 16-bit Dalvik instruction set directly on the local variables. Local variables are usually from 4 "virtual register" field. This reduces the instruction count Dalvik improve the translation speed. 
 When Android starts, Dalvik VM monitor all programs (APK), and create a dependency tree, optimized code for each program and stored in the Dalvik cache. After the first load Dalvik Cache file will be generated to provide the next load quickly, so the first time will be very slow.
 Dalvik interpreter using precalculated good Goto address, each instruction memory accesses are aligned on 64-byte boundary. After such time the look-up table saves one instruction. In order to strengthen the function, Dalvik also provides fast translator (Fast Interpreter).

In general, based on a stack machine instructions must be used to load and manipulate data from the stack, therefore, based on the relative machine registers, they require more instructions to achieve the same performance. However, based on the instruction register machine it must be encoded, and therefore, they are often more instructions.

Dalvik virtual machine neither supports Java ME does not support Java SE class libraries (such as: Java classes, AWT and Swing are not supported). Instead, it uses the library (Apache Harmony Java is a subset of) their own creation.

2.3 What is ART?

That Android Runtime
mechanism ART and Dalvik different. In Dalvik, each time the application is running, bytecode need time compiler (just in time, JIT) is converted to machine code, which will slow down the efficiency of the application, and in ART environment, applications in the first when first installed, it will pre-compiled bytecode into machine code, making it a truly local application. This process is called pre-compiler (AOT, Ahead-Of-Time ). In this case, start the application of the (first) and execution will become more rapid.

2.4 ART What advantages and disadvantages do?

Advantages:
1, a significant increase in system performance.
2, application start up faster, run faster, smoother experience, tactile feedback more timely.
3, longer battery life.
4, lower hardware support.
Disadvantages:
greater storage space 1. The machine code, machine code following the byte code becomes, may increase by 10% -20% (in the application package, however, is often only part of the executable code such as the latest Google+ APK. is 28.3 MB, but the code is only 6.9 MB.)
mounting 2. application time becomes longer.

tips: Now most of the smart phone allows users to choose to use Dalvik or ART mode. Of course, the default is to use Dalvik mode.
Usage: Settings - Accessibility - Developer options (Developer Tools) - Select the operating environment (step different phone settings may be different).

Three, ClassLoader constructor

 
19956127-82e2b33bc744d513.png
 

3.1 BaseDexClassLoader Constructor

PathClassLoader and DexClassLoader are inherited BaseDexClassLoader, take a look here. BaseDexClassLoader constructor.

public class BaseDexClassLoader extends ClassLoader {
    private final DexPathList pathList;

    /**
     * Constructs an instance.
     *
     * @param dexPath the list of jar/apk files containing classes and
     * resources, delimited by {@code File.pathSeparator}, which
     * defaults to {@code ":"} on Android
     * @param optimizedDirectory directory where optimized dex files
     * should be written; may be {@code null}
     * @param libraryPath the list of directories containing native
     * libraries, delimited by {@code File.pathSeparator}; may be
     * {@code null}
     * @param parent the parent class loader
     */
    public BaseDexClassLoader(String dexPath, File optimizedDirectory,
            String libraryPath, ClassLoader parent) {
        super(parent);
        this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
    }
}

BaseDexClassLoader constructor has four parameters, the following meanings:

  • dexPath : a list of files to be loaded, the file can be included classes.dex of JAR / APK / ZIP, classes.dex files can also be used directly with multiple files ":" Split
  • optimizedDirectory : dex optimized storage, can be empty
  • LibraryPath : storage directory to load the native library
  • parent: 父 ClassLoader

By the constructor we can probably understand operation mode BaseDexClassLoader, passing dex file, and then optimize, optimize dex files saved to optimizedDirectory directory.

3.2 PathClassLoader Constructor

Then we look at PathClassLoader constructor.

/**
 * Provides a simple {@link ClassLoader} implementation that operates on a list
 * of files and directories in the local file system, but does not attempt to
 * load classes from the network. Android uses this class for its system class
 * loader and for its application class loader(s).
 */
public class PathClassLoader extends BaseDexClassLoader {
    public PathClassLoader(String dexPath, ClassLoader parent) {
        super(dexPath, null, null, parent);
    }

    /**
     * Creates a {@code PathClassLoader} that operates on two given
     * lists of files and directories. The entries of the first list
     * should be one of the following:
     *
     * <ul>
     * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file as
     * well as arbitrary resources.
     * <li>Raw ".dex" files (not inside a zip file).
     * </ulyanzheng>
     *
     * The entries of the second list should be directories containing
     * native library files.
     *
     * @param dexPath the list of jar/apk files containing classes and
     * resources, delimited by {@code File.pathSeparator}, which
     * defaults to {@code ":"} on Android
     * @param libraryPath the list of directories containing native
     * libraries, delimited by {@code File.pathSeparator}; may be
     * {@code null}
     * @param parent the parent class loader
     */
    public PathClassLoader(String dexPath, String libraryPath,
            ClassLoader parent) {
        super(dexPath, null, libraryPath, parent);
    }
}

About PathClassLoader a little a little note, code comments in the introduction of PathClassLoader that used a series of files and directories on a file system operations ClassLoader implementation. Which did not mention the apk file can only be loaded after installation.
PathClassLoader has two constructors, the difference is whether to pass BaseDexClassLoader libraryPath empty. When the final call BaseDexClassLoader constructor, incoming optimizedDirectory is empty.

3.3 DexClassLoader Constructor

Let's look at DexClassLoader constructor. And parameters BaseDexClassLoader constructor is the same.

public class DexClassLoader extends BaseDexClassLoader {
    /**
     * Creates a {@code DexClassLoader} that finds interpreted and native
     * code.  Interpreted classes are found in a set of DEX files contained
     * in Jar or APK files.
     *
     * <p>The path lists are separated using the character specified by the
     * {@code path.separator} system property, which defaults to {@code :}.
     *
     * @param dexPath the list of jar/apk files containing classes and
     *     resources, delimited by {@code File.pathSeparator}, which
     *     defaults to {@code ":"} on Android
     * @param optimizedDirectory directory where optimized dex files
     *     should be written; must not be {@code null}
     * @param librarySearchPath the list of directories containing native
     *     libraries, delimited by {@code File.pathSeparator}; may be
     *     {@code null}
     * @param parent the parent class loader
     */
    public DexClassLoader(String dexPath, String optimizedDirectory,
            String librarySearchPath, ClassLoader parent) {
        super(dexPath, new File(optimizedDirectory), librarySearchPath, parent);
    }
}

By analyzing the constructor of the face, we can understand, PathClassLoader and DexClassLoader key differences in the optimizedDirectory parameters, PathClassLoader passed is null, and DexClassLoader is passed in a user-specified directory.

Fourth, parents delegate mechanism

4.1 Model Description

 
944365-cdd4548d762686c2.png
image

4.2 Workflow explain

  • Parents delegate workflow model code is implemented in java.lang.ClassLoader的loadClass()the
  • details as follows
@Override 
protected Class<?> loadClass(String name, boolean resolve) 
        throws ClassNotFoundException { 
    Class<?> c = findLoadedClass(name); 

  // 检查需要加载的类是否已经被加载过
    if (c == null) { 
        try { 
             // 若没有加载,则调用父加载器的loadClass()方法
            if (parent != null) { 
                c = parent.loadClass(name, false); 
            }else{ 
                // 若父类加载器为空,则默认使用启动类加载器作为父加载器
                c=findBootstrapClassOrNull(name); 
            } 
        } catch (ClassNotFoundException e) { 
            // 若父类加载器加载失败会抛出ClassNotFoundException, 
            //说明父类加载器无法完成加载请求 
        } 
        if(c==null){ 
            // 在父类加载器无法加载时 
            // 再调用本身的findClass方法进行类加载 
            c=findClass(name); 
        } 
    } 
    if(resolve){ 
        resolveClass(c); 
    } 
    return c; 
}

Summary of steps : a class loader when the class loader receives a request

  1. The class loader delegates to the parent class loader to complete, but will not own to load the class

Each class loader is true, all load request should ultimately be transferred to the top of the boot class loader

  1. Only when the parent class loader feedback they can not handle the load request (its search did not find the desired category), will own child loader to load

4.3 advantage

JavaWith its class includes a class loader A tape together priority hierarchy

  1. Such as: type java.lang.Object(stored in rt.jar) is in the loading process, whichever class loader to load a class, will ultimately be delegated to a top loading model boot class loader, so Objectthe class loader environment in various types of program They are the same class.
  2. If parents do not use the delegate model (that is, to load themselves by each class loader), wrote a user java.lang.Objectclass (on ClassPaththe), a number of different systems that appear in the Objectclass, Java system, the most basic of behavior can not be Guarantee

After the finished system class loader, below I will explain how the needs of custom class loader based on.
More Android Video Advanced Architecture Advanced Learning Click: https://space.bilibili.com/474380680

Recommended reading: Transfer from "Tencent senior wrote an open letter to the national mobile Internet workers."

Reference: https://www.jianshu.com/p/8743d8062bb6
https://blog.csdn.net/m_sdn/article/details/84856273
https://www.jianshu.com/p/58f817d176b7
HTTPS: // segmentfault .com / a / 1190000020254261

Guess you like

Origin www.cnblogs.com/Android-Alvin/p/11949024.html