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

1.Javassist 简介

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

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

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{voidapply(Project project) {

project.logger.error("Dhjar start=========================")

project.extensions.create("dhjar", LJarConfig)

project.android.registerTransform(newJavassistTransform(project))

}

}

transform的几个方法

//获取输入类型jar或者class

@Overridepublic SetgetInputTypes() {returnTransformManager.CONTENT_CLASS;

}

//需要处理的范围, 主项目 子项目 或者三方库

@Overridepublic Set super QualifiedContent.Scope>getScopes() {

Set sets = new HashSet()

sets.add(QualifiedContent.Scope.EXTERNAL_LIBRARIES)returnsets;

}

@Override

Set super QualifiedContent.Scope>getReferencedScopes() {

Set sets = new HashSet()

sets.add(QualifiedContent.Scope.EXTERNAL_LIBRARIES)

sets.add(QualifiedContent.Scope.PROVIDED_ONLY)returnsets

}

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

@Overridepublic void transform(TransformInvocation transformInvocation) throwsIOException {

}

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

private static void modify(CtClass c, ClassPool mClassPool,Listmethods) {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= newStringBuffer()

sb.append("{try{")if(!ctMethod.getReturnType().getName().contains("void")){

sb.append("return ")

}

sb.append(method2)

sb.append("(")for(int i = 0; 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 或造成空指针崩溃

packagecom.vova.testlibrary;public classTestFile

{public intgetInt()

{return 1;

}public floatgetFloat()

{return 0.0F;

}public doublegetDoulbe()

{return 0.0D;

}public longgetLong()

{return 0L;

}public chargetChar()

{return 'a';

}public shortgetShort()

{return 0;

}public doublegetDouble()

{return 0.0D;

}publicString getString()

{

String aa= null;int len =aa.length();return null;

}public bytegetByte()

{return 0;

}

}

View Code

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

下面是19.jar源码

packagecom.vova.testlibrary;importjava.io.PrintStream;public classTestFile

{public intgetIntDhCut()

{return 1;

}public floatgetFloatDhCut()

{return 0.0F;

}public doublegetDoulbe()

{return 0.0D;

}public longgetLongDhCut()

{return 0L;

}public chargetCharDhCut()

{return 'a';

}public shortgetShortDhCut()

{return 0;

}public doublegetDoubleDhCut()

{return 0.0D;

}publicString getStringDhCut()

{

String aa= null;int len =aa.length();return null;

}public bytegetByteDhCut()

{return 0;

}public intgetInt()

{try{returngetIntDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return 0;

}public floatgetFloat()

{try{returngetFloatDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return 0.0F;

}public longgetLong()

{try{returngetLongDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return 0L;

}public chargetChar()

{try{returngetCharDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return 'a';

}public shortgetShort()

{try{returngetShortDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return 0;

}public doublegetDouble()

{try{returngetDoubleDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return 0.0D;

}publicString getString()

{try{returngetStringDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return null;

}public bytegetByte()

{try{returngetByteDhCut();

}catch(Exception localException)

{

System.out.println(localException.toString());

localException.printStackTrace();

}return 0;

}

}

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值