技术经验谈 技术经验谈
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

hss01248

一号线程序员
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 最佳实践

  • ui

  • 优化

  • aop

    • ASM
    • aop
    • aspecj的一些常用语法
    • 随意修改第三方库代码
      • 给ARouter的回调NavigationCallback增加一个onActivityResult方法
        • 前提: 已有工具库:
        • 1.增加方法:
        • 2. 让回调生效:
      • 给arouter的关键步骤增加log日志,乃至记录到数据库,以便debug
  • apm

  • 架构

  • webview

  • rxjava

  • activity-fragment-view的回调和日志
  • Android加密相关
  • Android命令行操作
  • app后台任务
  • kotlin
  • kotlin漫谈
  • kotlin语言导论
  • sentry上传mapping.txt文件
  • so放于远程动态加载方案
  • states
  • Xposed模块开发
  • 一个关于manifest合并的猥琐操作
  • 玩坏android存储
  • 获取本app的安装来源信息
  • Android
  • aop
hss01248
2021-06-21
目录

随意修改第三方库代码

# 随意修改第三方库源码

以arouter为例

  • 如何给一个类/接口增加方法/属性,且能在编码时调用此新增方法?
  • 如何修改一个方法的内容?

arouter-api-onActivitResult (opens new window)

这里有两个需求:

# 给ARouter的回调NavigationCallback增加一个onActivityResult方法

通过

ARouter.getInstance().navigation(mContext, this, requestCode, callback)
1

直接在回调里收到onActivityResult的结果.

# 前提: 已有工具库:

通过api 'com.github.hss01248.StartActivityResult:activityresult:1.0.2'库,可一行代码实现activity回调:

StartActivityUtil.startActivity(activity, null, intent, requestCode != 0
                    , new TheActivityListener<Activity>() {
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
                            super.onActivityResult(requestCode, resultCode, data);
                            if (callback != null) {
                                callback.onActivityResult(requestCode, resultCode, data);
                            }
                        }

                        @Override
                        public void onActivityNotFound(Throwable e) {
                            super.onActivityNotFound(e);
                            if (callback != null) {
                                callback.onLost(postcard);
                            }

                        }
                    });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

关键在于,如何给com.alibaba:arouter-api 库里的NavigationCallback增加一个原先不存在的onActivityResult方法,且使其起作用.

# 1.增加方法:

写一个同包名同路径的接口类,新增onActivityResult方法

使用classpath "com.github.skyNet2017:JarFilterPlugin:2.5.5"插件,打包时排除掉arouter-api库里的NavigationCallback,从而让我们自己写的这个多了方法的NavigationCallback生效.

# 2. 让回调生效:

找到arouter-api 里startActivityForReuslt的代码,使用aspectjx进行切入,替换掉整个方法的实现:

@Aspect
public class ARouterAspect {

    @Around("execution(* com.alibaba.android.arouter.launcher._ARouter.startActivity(..))")
    public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Object result = null;
        
        final int requestCode = (int) args[0];
        Context currentContext = (Context) args[1];
        Intent intent = (Intent) args[2];
        final Postcard postcard = (Postcard) args[3];
        final NavigationCallback callback = (NavigationCallback) args[4];

        if (currentContext instanceof FragmentActivity) {
            FragmentActivity activity = (FragmentActivity) currentContext;
            StartActivityUtil.startActivity(activity, null, intent, requestCode != 0
                    , new TheActivityListener<Activity>() {
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
                            super.onActivityResult(requestCode, resultCode, data);
                            if (callback != null) {
                                callback.onActivityResult(requestCode, resultCode, data);
                            }
                        }

                        @Override
                        public void onActivityNotFound(Throwable e) {
                            super.onActivityNotFound(e);
                            if (callback != null) {
                                callback.onLost(postcard);
                            }

                        }
                    });
        } else {
            ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle());
        }

        if ((-1 != postcard.getEnterAnim() && -1 != postcard.getExitAnim()) && currentContext instanceof Activity) {    // Old version.
            ((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim());
        }

        if (null != callback) { // Navigation over.
            callback.onArrival(postcard);
        }

        return result;
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

注意增加混淆规则,以及aspecjx的include配置

# 给arouter的关键步骤增加log日志,乃至记录到数据库,以便debug

找到切入点,aspectj切入. callback为接口,使用动态代理注入替换即可

@Aspect
public class ArouterLogAspect {

    @Around("execution(* com.alibaba.android.arouter.launcher.ARouter.navigation(..))")
    public Object callbackProxy(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        if(args.length != 4){
            return joinPoint.proceed(args);
        }
        NavigationCallback callback = (NavigationCallback) args[3];
        args[3] = LogProxy.getProxy(callback);
        return joinPoint.proceed(args);
    }
    
    @Around("execution(* com.alibaba.android.arouter.facade.Postcard.setProvider(..))")
    public Object providerProxy(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        IProvider provider = (IProvider) args[0];
        args[0] = LogProxy.getProxy(provider);
        return joinPoint.proceed(args);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
编辑 (opens new window)
上次更新: 2022/08/25, 20:20:31
aspecj的一些常用语法
android apm性能监控方案

← aspecj的一些常用语法 android apm性能监控方案→

最近更新
01
截图后的自动压缩工具
12-27
02
图片视频文件根据exif批量重命名
12-27
03
chatgpt图片识别描述功能
02-20
更多文章>
Theme by Vdoing | Copyright © 2020-2025 | 粤ICP备20041795号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式