android用 javassist实现捕获第三方库异常

android用 javassist实现捕获第三方库异常,第1张

概述Git传送门 Android开发中不可避免的会用到很多第三方库, 如果碰到异常 常常有种心有余而力不足的想法,当日,如果是开源的 你可以吧源码导入进来进行修改, 但不可避免的会造成维护性差, 本文提供一个捕获第三方库异常的思路,也可以扩展为在编译时修改第三方代码,从而插入自己的需求 1.Javassist 简介   javassist是一个修改java字节码的开源库  下面是个很简单的例子,获取一

Git传送门

AndroID开发中不可避免的会用到很多第三方库, 如果碰到异常 常常有种心有余而力不足的想法,当日,如果是开源的 你可以吧源码导入进来进行修改,

但不可避免的会造成维护性差, 本文提供一个捕获第三方库异常的思路,也可以扩展为在编译时修改第三方代码,从而插入自己的需求

1.Javassist 简介

  javassist是一个修改java字节码的开源库

 下面是个很简单的例子,获取一个classpool,设置运行所需要的库,写入到对应位置

 具体语法可以参考 Javassist介绍

Classpool pool = Classpool.getDefault();
pool.insertClasspath("/usr/local/javalib");
CtClass cc = pool.get("test.Rectangle");cc.setSuperclass(pool.get("test.Point"));cc.writefile();
 2.在安卓中的应用

 gradle 编译安卓项目是通过一个个task来执行任务, 我们可以通过gradle看到很多transform*的task

 在编译时插入一个自己的transform 从而实现对源码或第三方jar库拦截 实现修改第三方库

下面时定义一个gradle插件, 注册一个自己的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))    }}

transform的几个方法 

//获取输入类型jar或者class  
@OverrIDe
public Set<QualifIEdContent.ContentType> getinputTypes() { return transformManager.CONTENT_CLASS; } //需要处理的范围, 主项目 子项目 或者三方库 @OverrIDe public Set<? super QualifIEdContent.Scope> getScopes() { Set<QualifIEdContent.Scope> sets = new HashSet<QualifIEdContent.Scope>() sets.add(QualifIEdContent.Scope.EXTERNAL_liBRARIES) return sets; } @OverrIDe 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 }

 

他的核心方法就是  分别为获取jar 和source目录

    @OverrIDe    public voID transform(transformInvocation transformInvocation) throws IOException {}

下面就是捕获第三方异常的核心代码 通过插入一个相同的方法包裹上try catch 从而拦截需要捕获的方法, 具体代码可以看开头的链接
    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())        }    }

 

 拦截前得类 此时我们直接调用getString 或造成空指针崩溃
@H_403_234@

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

 

   gradle编译效果图   输入test.jar   输出19.jar  打印需要替换的方法

下面是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 总结

以上是内存溢出为你收集整理的android用 javassist实现捕获第三方库异常全部内容,希望文章能够帮你解决android用 javassist实现捕获第三方库异常所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1121563.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存