如何利用反射去实现定制化flavor java代码,慎用,骚操作.

前提条件:

  • 反射是一种不安全的操作,慎用.
  • 了解android组件化开发,可以点击了解
  • 了解一定的java反射逻辑和知识.可以点击了解
  • 熟练掌握Android flavor,可以点击了解

技能点

  • 反射
  • 动态代理
  • module组件化开发,便于后期维护

需求背景:

  • 在某个flavor下,做一些定制的java逻辑和代码,但是这些代码和相关的三方的sdk,都不参与其他的flavor的编译过程.

说明:

首先说一下什么是Android 的 flavor , 其实,这个是Android差异化打包所衍生出来的,或者说,差异化打包的实现就是通过flavor,什么是差异化打包呢?其实就是一套代码,有具体的公共的功能,但是,可能资源文件,以及图片资源不一样,以及最重要的不一样,可能在你看起来,这两个app都是差不多的,除了图片资源不一样意外,功能都是一样的,但是从代码层面来讲,他们就是两个不同的app,因为applicationId不一样,所以,打开时候,他们的进程pid是不同的,所以,他们是两个app,ok,不说那么多,如果知道productFlavors同学可能会问,为什么不能直接将代码写在公共类库,用flavor去区分就行了,比如说我现在是flavor A, 那么我就执行这个代码,flavor B就不执行,ok,思路完全也没有问题,代码也能够实现,但是,有个问题,随着现在的安全与各种检查越来越严格,因为你的代码最终是服务于客户,那么,在对于客户A,他需要这个功能,没啥好说,但是,对于客户B来说,我不需要这个功能,检测到某些权限和代码对于客户B来说,是属于敏感权限,而这些敏感权限正好是客户A要求你开发的代码,那么怎么办?
\color{red}{所以,我们需要做,代码隔离,即在flavorA的情况下,将定制化代码进行编译,在flavorB的时候,相关的代码不参与编译}
有同学说,这个简单,在导包时候,使用 flavor+complie 这种方式,在指定的flavor上编译,但是,这样会有问题,因为我们java代码和C代码,都会有import头文件,这个如果切换到其他的flavor时候,那么,你某些资源没有参与编译,
那么,就会导致你import导包失败,在其他的flavor上,代码编译无法通过.所以,有两种解决方法.

解决方法

  • 1 将差异化代码的整理出来,实现两个不同的module,moduleA放置差异化的内容,moduleB什么都不放,保持和moduleA相同的类路径就行了,这样,在不同的flavor去加载不同的module,然后,A和B分别创建一个名字一样用于事件分发的入口,这样,就不会存在import 导包报错的问题,因为路径一样,入口一样.
  • 2 基于1的思路,只需要创建一个moduleA,创建入口,通过反射拿到入口并实例化,调用代码,so,我们来详细讲这种方法,项目结构如下
    QQ20211222-153418.png

    我们将第三方,定制化的代码放入到这个module下.
    QQ20211222-153612.png

    在引入的时候,我们使用方式,这样,只会在当前的flavor中被编译
    QQ20211222-153852.png

    这个module中只有两个,一个统一的管理入口,一个回调实现类,为什么会有一个回调的实现类,这就是我下面会说的.
    我们都知道,反射,只能反射类,也能反射类的方法,那么类的方法中如果有接口怎么办,我们怎么收到这个接口的回调,那么我们就需要动态代理,这个不在赘述,具体的流程是如下图所示
    QQ20211222-154429.png

    我写一个类去继承InvocationHandler,这样,相当于我动态代理的类,他的实现方法会回调在invoke方法中,
    这样,我去获取一个已经实现了接口的实现类,就可以在invoke返回一个已经实现的方法.
    QQ20211222-154802.png

    这一段代码,是将你需要代理的类和中间的实现类绑定关系,我们可以看看原来的方法,如下图所示
    QQ20211222-155017.png

    这个就是你需要传入一个callbak的实现类,所以,我们通过动态代理,实现了callBack,我们将callBack传入方法中,那么就可以得到invoke的回调,那么我们自然就知道,当前哪个接口需要实现,也就拿到了接口回调.
    但是,反射毕竟是不安全的一种操作,尽量还是少用反射.

你可能感兴趣的:(如何利用反射去实现定制化flavor java代码,慎用,骚操作.)