项目作者: TheMelody

项目描述 :
Kotlin Aspectj
高级语言: Kotlin
项目地址: git://github.com/TheMelody/kotlin_plugin_aop.git
创建时间: 2018-11-30T06:15:50Z
项目社区:https://github.com/TheMelody/kotlin_plugin_aop

开源协议:

下载


Kotlin版本的Aspectj切面玩法 :see_no_evil:

我的知乎 我的知乎

我们先介绍如何集成进我们的项目中,然后再介绍如何使用

首先我们需要把version.gradle
(公共版本配置)粘贴在project的根目录

1.project root的src下面的build.gradle中配置plugin

  1. 我们在rootbuild.gradle文件内容的最上层增加
  2. apply from: 'version.gradle'
  3. 然后在buildscript内部增加下面的内容:
  4. repositories {
  5. maven {
  6. url "https://jitpack.io"
  7. }
  8. //等等更多其他仓库地址,maven里面的这个地址是必须要的
  9. }
  10. dependencies {
  11. classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.10"
  12. classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4'
  13. }

增加了version.gradle之后你们如果想要修改kotlin和aspectj的版本都可以在version.gradle中修改了

2.app下面的build.gradle中配置plugin

  1. apply plugin: 'kotlin-android'
  2. apply plugin: 'kotlin-android-extensions'
  3. apply plugin: 'android-aspectjx'

这三个plugin需要配置在默认的plugin下面

  • apply plugin: ‘com.android.application’

接下来配置aspectj需要过滤的其他库,具体可以参考Aspectj语法,默认不做任何配置的话,
会遍历项目编译后所有的 .class 文件和依赖的第三方库进行处理。我们通过exclude过滤缩小范围

  1. android {
  2. aspectjx {
  3. exclude 'org.jetbrains.kotlin'
  4. exclude 'org.jetbrains.kotlinx'
  5. exclude 'com.android.support'
  6. }
  7. }

3.build.gradle依赖远程libary

  1. implementation 'aop.kotlinx.plugin:kotlin_plugin_aop:1.0.6'

:see_no_evil:前方高能,接下来我们就可以使用我们的aop插件了

目前我们提供四个功能:


防止控件重复点击


第一种默认时间间隔600毫秒
  1. @SingleClick
  2. fun testSingleClick(){
  3. Log.d(TAG,"testSingleClick()")
  4. }
第二种自定义时间间隔,毫秒值
  1. @SingleClick(timeInterval = 1000)
  2. fun testSingleClick(){
  3. Log.d(TAG,"testSingleClick()")
  4. }

开发模式下-打印方法耗时


  1. @DebugTimeTrace(value = "登录")
  2. fun doLogin(){
  3. //不可描述的耗时
  4. }

运行时权限申请


  1. @CheckPermission(requestCode = 1001, permissions = [Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA])
  2. fun chooseAlbum(){
  3. //权限申请写和相机权限,样例
  4. }
我们需要在Activity或者Fragment中复写
  1. override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray)

我们需要在这个回调方法上面增加授权结果的注解 @OnRequestPermissionsResult
这个注解类默认的参数是false

  1. annotation class OnRequestPermissionsResult(val useDefaultDeniedDialog:Boolean = false)

如果我们配置成了true,则使用我们写好的默认权限拒绝的提示dialog,

如果我们配置成了true,那么我们需要在res目录下的values.xml中

增加如下内容:

(如果你用默认的false,则不需要配置这三个string值)
  1. <string name="dialog_aop_permission_title">提示</string>
  2. <string name="dialog_aop_permission_message">当前应用缺少必要权限。\n\n请点击\"设置\"-\"权限\"-打开如下权限:</string>
  3. <string name="dialog_aop_permission_message_no_details">当前应用缺少必要权限。\n\n请点击\"设置\"-\"权限\"-打开所需的权限。</string>

如果你配置成了true那么你只需在回调上方增加@OnRequestPermissionsResult(useDefaultDeniedDialog = true)就结束了
如果你使用默认的false,那么你需要自己处理权限拒绝之后的处理逻辑,如下方法demo:

  1. @OnRequestPermissionsResult
  2. override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
  3. super.onRequestPermissionsResult(requestCode, permissions, grantResults)
  4. if(requestCode==1001){//这个和你的请求的code需要匹配
  5. permissions.classCast<Array<String>>()?.let {
  6. PermissionUtils.getLackedPermissionList(this, it).let { lackedList ->
  7. //不可描述......
  8. }
  9. }
  10. }
  11. }
  12. 对于上面的onRequestPermissionsResult()方法里面的, permissions.classCast<T>()的方法使用如下:
  13. //防止类型擦除,reified具体化一个T的类型参数
  14. inline fun <reified T> Any.classCast() : T? = this as? T?

悬浮窗权限申请


  1. @CheckDrawOverLaysPermission
  2. fun checkFloatWindow(){
  3. //悬浮窗权限有了,可以做下面的事情了
  4. }

如果自己要控制悬浮窗检查可以使用下面两个方法:

  1. 检测是否授权悬浮窗权限了,true授权了,false没有授权
  2. aop.kotlin.plugin.PermissionUtils#canDrawOverlays
  3. 跳转到悬浮窗授权界面
  4. aop.kotlin.plugin.PermissionUtils#openDrawOverlaysActivity

登录拦截


我们在Application的onCreate中初始化拦截器

  1. override fun onCreate() {
  2. super.onCreate()
  3. LoginHandlerInterceptor.instance.init(object : ILoginListener {
  4. override fun onInterceptor(interceptorType: Int): Boolean {//类型自己定义
  5. if(interceptorType==0){
  6. //跳转到登录界面,弹dialog,自己随意
  7. return true
  8. }else if(interceptorType==1){
  9. Log.d(TAG,"不拦截,方法执行不受影响,打开其他界面,可以弹Toast")
  10. return false
  11. }else if(interceptorType==2){
  12. }else if(更多自己定义的类型){
  13. }
  14. return true
  15. }
  16. override fun isLogin(): Boolean {
  17. return false //自己项目根据自己项目情况判断当前是否是登录状态
  18. }
  19. })
  20. }

onInterceptor方法如果返回true,注解的方法不会继续执行,如果返回false,方法继续执行不受影响。

注解的用法如下:

  1. @LoginInterceptor(interceptorType = 0)
  2. fun testMethod(){
  3. //执行其他业务逻辑
  4. //interceptorType定义的类型,我们在Application中要对你定义的类型做拦截
  5. }

:clap: 用法全部介绍完,有新的想法可以提出来

写在最后,混淆配置

  1. -keep class * extends java.lang.annotation.Annotation { *; }
  2. -keep interface * extends java.lang.annotation.Annotation { *; }
  3. -keep @aop.kotlin.plugin.annotation.CheckPermission class * {*;}
  4. -keep class * {
  5. @aop.kotlin.plugin.annotation.CheckPermission <fields>;
  6. }
  7. -keepclassmembers class * {
  8. @aop.kotlin.plugin.annotation.CheckPermission <methods>;
  9. }
  10. -keep @aop.kotlin.plugin.annotation.OnRequestPermissionsResult class * {*;}
  11. -keep class * {
  12. @aop.kotlin.plugin.annotation.OnRequestPermissionsResult <fields>;
  13. }
  14. -keepclassmembers class * {
  15. @aop.kotlin.plugin.annotation.OnRequestPermissionsResult <methods>;
  16. }
  17. -keep @aop.kotlin.plugin.annotation.SingleClick class * {*;}
  18. -keep class * {
  19. @aop.kotlin.plugin.annotation.SingleClick <fields>;
  20. }
  21. -keepclassmembers class * {
  22. @aop.kotlin.plugin.annotation.SingleClick <methods>;
  23. }
  24. -keep @aop.kotlin.plugin.annotation.LoginInterceptor class * {*;}
  25. -keep class * {
  26. @aop.kotlin.plugin.annotation.LoginInterceptor <fields>;
  27. }
  28. -keepclassmembers class * {
  29. @aop.kotlin.plugin.annotation.LoginInterceptor <methods>;
  30. }
  31. -keep @aop.kotlin.plugin.annotation.DebugTimeTrace class * {*;}
  32. -keep class * {
  33. @aop.kotlin.plugin.annotation.DebugTimeTrace <fields>;
  34. }
  35. -keepclassmembers class * {
  36. @aop.kotlin.plugin.annotation.DebugTimeTrace <methods>;
  37. }
  38. -keep @aop.kotlin.plugin.annotation.CheckDrawOverLaysPermission class * {*;}
  39. -keep class * {
  40. @aop.kotlin.plugin.annotation.CheckDrawOverLaysPermission <fields>;
  41. }
  42. -keepclassmembers class * {
  43. @aop.kotlin.plugin.annotation.CheckDrawOverLaysPermission <methods>;
  44. }