android achieve capture third-party libraries abnormality javassist

Git Portal

Android development will inevitably use a lot of third-party libraries, if you encounter a kind of very difficult and often abnormal thoughts of the day, if it is open source you can modify the source code imports come in,

But inevitably cause poor maintenance, we provide a third-party library to capture unusual ideas can be extended to a third party to modify the code at compile time, so insert your own needs

1.Javassist Profile

  javassist is a modified open source library java bytecode

 Here is a very simple example, a Get the ClassPool, set to run the required libraries, written to the corresponding position

 Concrete syntax can refer  Javassist Introduction

ClassPool pool = ClassPool.getDefault();
pool.insertClassPath("/usr/local/javalib");
CtClass cc = pool.get("test.Rectangle");
cc.setSuperclass(pool.get("test.Point"));
cc.writeFile();

 2. Application of Andrews

 Andrews gradle compile the project is to perform one task by task, we can see a lot of task by gradle transform *

 At compile time insert a transform order to achieve their own or third-party source code library jar interception achieve modify third-party libraries

The following definition of a gradle plug when registering an own transform

public class MainPlugin implements Plugin<Project>{
    void apply(Project project) {
        project.logger.error("Dhjar start=========================")
        project.extensions.create("dhjar", LJarConfig)
        project.android.registerTransform(new JavassistTransform(project))
    }
}

Several ways to transform the 

// Get Input jar type or class   
@Override
public the Set <QualifiedContent.ContentType> getInputTypes, () { return TransformManager.CONTENT_CLASS; } scope // need of treatment, main constituents library item or sub @Override public the Set <? Super QualifiedContent. the Scope> getScopes () { the Set <QualifiedContent.Scope> = sets new new HashSet <QualifiedContent.Scope> () sets.add (QualifiedContent.Scope.EXTERNAL_LIBRARIES) return sets; } @Override the Set <? Super QualifiedContent.Scope> getReferencedScopes() { Set<QualifiedContent.Scope> sets = new HashSet<QualifiedContent.Scope>() sets.add(QualifiedContent.Scope.EXTERNAL_LIBRARIES) sets.add(QualifiedContent.Scope.PROVIDED_ONLY) return sets }

 

His heart is to obtain respectively jar and source directory

    @Override
    public void transform(TransformInvocation transformInvocation) throws IOException {
}

Here is a third-party capture the exception of the core code by inserting a wrap on the same method as a method to intercept try catch so you need to capture the specific code can see the link at the beginning of
    private static void modify(CtClass c, ClassPool mClassPool,List<String> methods) {
        if (c.isFrozen()) {
            c.defrost()
        }
        System.out.println("find class==============="+c.getName())
        for(String method : methods){
            CtMethod ctMethod = c.getDeclaredMethod(method)
            String method2 = method+"DhCut"
            CtMethod ctMethod2 = CtNewMethod.copy(ctMethod,method2,c,null)
            c.addMethod(ctMethod2)
            int methodLen = ctMethod.getParameterTypes().length
            StringBuffer sb  = new StringBuffer()
            sb.append("{try{")
            if(!ctMethod.getReturnType().getName().contains("void")){
                sb.append("return ")
            }
            sb.append(method2)
            sb.append("(")
            for(int i = 0; i<methodLen;i++){
                sb.append("\$"+(i+1))
                if(i!=methodLen-1){
                    sb.append(",")
                }
            }
            sb.append(");}catch(Exception ex){ System.out.println(ex.toString());ex.printStackTrace();}")
            if(!ctMethod.getReturnType().getName().contains("void")){
                sb.append("return ")
                String result = getReturnValue(ctMethod.getReturnType().getName())
                sb.append(result)
                sb.append(";")
            }
            sb.append("}")
           System.out.println("return type  =======" +ctMethod.getReturnType().getName())
            ctMethod.setBody(sb.toString())
        }
    }

 

 At this point we have to intercept before the class directly call getString or cause a null pointer crash
package com.vova.testlibrary;

public class TestFile
{
  public int getInt()
  {
    return 1;
  }
  
  public float getFloat()
  {
    return 0.0F;
  }
  
  public double getDoulbe()
  {
    return 0.0D;
  }
  
  public long getLong()
  {
    return 0L;
  }
  
  public char getChar()
  {
    return 'a';
  }
  
  public short getShort()
  {
    return 0;
  }
  
  public double getDouble()
  {
    return 0.0D;
  }
  
  public String getString()
  {
    String aa = null;
    int len = aa.length();
    return null;
  }
  
  public byte getByte()
  {
    return 0;
  }
}
View Code

 

   FIG effect gradle compiling input test.jar 19.jar output printing method needs to be replaced

Here is the source 19.jar
package com.vova.testlibrary;

import java.io.PrintStream;

public class TestFile
{
  public int getIntDhCut()
  {
    return 1;
  }
  
  public float getFloatDhCut()
  {
    return 0.0F;
  }
  
  public double getDoulbe()
  {
    return 0.0D;
  }
  
  public long getLongDhCut()
  {
    return 0L;
  }
  
  public char getCharDhCut()
  {
    return 'a';
  }
  
  public short getShortDhCut()
  {
    return 0;
  }
  
  public double getDoubleDhCut()
  {
    return 0.0D;
  }
  
  public String getStringDhCut()
  {
    String aa = null;
    int len = aa.length();
    return null;
  }
  
  public byte getByteDhCut()
  {
    return 0;
  }
  
  public int getInt()
  {
    try
    {
      return getIntDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return 0;
  }
  
  public float getFloat()
  {
    try
    {
      return getFloatDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return 0.0F;
  }
  
  public long getLong()
  {
    try
    {
      return getLongDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return 0L;
  }
  
  public char getChar()
  {
    try
    {
      return getCharDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return 'a';
  }
  
  public short getShort()
  {
    try
    {
      return getShortDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return 0;
  }
  
  public double getDouble()
  {
    try
    {
      return getDoubleDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return 0.0D;
  }
  
  public String getString()
  {
    try
    {
      return getStringDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return null;
  }
  
  public byte getByte()
  {
    try
    {
      return getByteDhCut();
    }
    catch (Exception localException)
    {
      System.out.println(localException.toString());
      localException.printStackTrace();
    }
    return 0;
  }
}
View Code

 

 

Guess you like

Origin www.cnblogs.com/dikeboy/p/11505800.html