├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── zj │ │ └── it │ │ └── bhne │ │ └── androidaop │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── zj │ │ │ └── it │ │ │ └── bhne │ │ │ └── androidaop │ │ │ ├── Main2Activity.java │ │ │ ├── MainActivity.kt │ │ │ └── OnClick.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ └── activity_main2.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── zj │ └── it │ └── bhne │ └── androidaop │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── singclick ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── zj │ │ └── singclick │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── zj │ │ │ └── singclick │ │ │ ├── OnClick.kt │ │ │ ├── SingleClick.java │ │ │ ├── SingleClickAspect.java │ │ │ └── XClickUtil.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── zj │ └── singclick │ └── ExampleUnitTest.java └── test ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── zj │ └── test │ └── ExampleInstrumentedTest.kt ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── zj │ │ └── test │ │ ├── TestActivity.kt │ │ └── reified.kt └── res │ ├── layout │ └── activity_test.xml │ └── values │ └── strings.xml └── test └── java └── com └── zj └── test └── ExampleUnitTest.kt /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndroidAOP 2 | 3 | > AOP的方式实现防止按钮多次点击,Java和Kotlin都能使用。 4 | 5 | 使用方法很简单,需要几步配置,配置完成之后直接添加注解即可使用,下面是配置方法: 6 | 7 | ## 引入 8 | 9 | 1. 在项目的`build.gradle`中的`buildscript`中的`dependencies`添加: 10 | 11 | ``` 12 | dependencies { 13 | ... 14 | classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10' 15 | } 16 | ``` 17 | 18 | 2. 在项目的`build.gradle`中的`allprojects`中的`repositories`添加: 19 | 20 | ``` 21 | allprojects { 22 | repositories { 23 | ... 24 | maven { url 'https://jitpack.io' } 25 | } 26 | } 27 | ``` 28 | 29 | 3. 在`app`的`build.gradle`中的最上面添加 30 | 31 | ``` 32 | apply plugin: 'android-aspectjx' 33 | ``` 34 | 35 | 4. 在`app`的`build.gradle`中的`dependencies`添加 36 | [![](https://jitpack.io/v/zhujiang521/AndroidAOP.svg)](https://jitpack.io/#zhujiang521/AndroidAOP) 37 | 38 | ``` 39 | implementation 'com.github.zhujiang521:AndroidAOP:1.1.1' 40 | ``` 41 | 42 | ## 使用方法 43 | 44 | 直接在按钮的点击事件上面添加注解即可使用。 45 | 46 | 在`Java`中: 47 | 48 | ``` 49 | @SingleClick 50 | @Override 51 | public void onClick(View v) { 52 | switch (v.getId()) { 53 | case R.id.btnClick2: 54 | ToastUtils.showShort("哈哈哈"); 55 | Log.e("刘沛星","wwww"); 56 | break; 57 | } 58 | } 59 | ``` 60 | 61 | 在`Kotlin`中: 62 | 63 | ``` 64 | @SingleClick 65 | override fun onClick(v: View?) { 66 | if (v != null) { 67 | when(v.id){ 68 | R.id.btnClick ->{ 69 | ToastUtils.showShort("哈哈哈") 70 | Log.e("刘沛星","wwww") 71 | } 72 | } 73 | } 74 | } 75 | ``` 76 | 77 | 默认间隔时间为`1500`毫秒,可以自行修改,在注解后面添加括号,在括号中声明需要的时间值即可。 78 | 79 | ``` 80 | @SingleClick(1000) 81 | override fun onClick(v: View?) { 82 | if (v != null) { 83 | when(v.id){ 84 | R.id.btnClick ->{ 85 | ToastUtils.showShort("哈哈哈") 86 | Log.e("刘沛星","wwww") 87 | } 88 | } 89 | } 90 | } 91 | ``` 92 | 93 | OK。 94 | 95 | 新增了`Kotlin`的判断重复的方法,大家可以按照下面的方法直接进行调用,比写注解更加灵活方便: 96 | 97 | ``` 98 | btnKuoZhan.setSafeListener { 99 | ToastUtils.showShort("222") 100 | Log.e("kuozhan","wwww") 101 | } 102 | ``` 103 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | apply plugin: 'android-aspectjx' 8 | android { 9 | compileSdkVersion 29 10 | defaultConfig { 11 | applicationId "zj.it.bhne.androidaop" 12 | minSdkVersion 21 13 | targetSdkVersion 29 14 | versionCode 1 15 | versionName "1.0" 16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | compileOptions { 25 | sourceCompatibility JavaVersion.VERSION_1_8 26 | targetCompatibility JavaVersion.VERSION_1_8 27 | } 28 | 29 | } 30 | 31 | dependencies { 32 | implementation fileTree(dir: 'libs', include: ['*.jar']) 33 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 34 | //noinspection GradleCompatible 35 | implementation 'com.android.support:appcompat-v7:28.0.0' 36 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 37 | 38 | //安卓Utils 39 | implementation 'com.blankj:utilcode:1.23.6' 40 | 41 | testImplementation 'junit:junit:4.12' 42 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 43 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 44 | implementation project(path: ':singclick') 45 | implementation project(path: ':test') 46 | } 47 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/zj/it/bhne/androidaop/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package zj.it.bhne.androidaop 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("zj.it.bhne.androidaop", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/zj/it/bhne/androidaop/Main2Activity.java: -------------------------------------------------------------------------------- 1 | package zj.it.bhne.androidaop; 2 | 3 | import android.app.ProgressDialog; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | import android.view.View; 8 | import android.widget.Button; 9 | 10 | import androidx.appcompat.app.AppCompatActivity; 11 | 12 | import com.blankj.utilcode.util.ToastUtils; 13 | import com.zj.singclick.SingleClick; 14 | import com.zj.test.TestActivity; 15 | 16 | 17 | public class Main2Activity extends AppCompatActivity{ 18 | 19 | private final static String TAG = "Main2Activity"; 20 | //全局定义 21 | private long lastClickTime = 0L; 22 | // 两次点击间隔不能少于1000ms 23 | private static final int FAST_CLICK_DELAY_TIME = 1000; 24 | 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | setContentView(R.layout.activity_main2); 30 | } 31 | 32 | /** 33 | * 弹窗等待 34 | * 35 | * @param view / 36 | */ 37 | public void btnDialog(View view) { 38 | ProgressDialog progressDialog = new ProgressDialog(this); 39 | progressDialog.setTitle("等待"); 40 | progressDialog.setMessage("等待内容"); 41 | progressDialog.setCanceledOnTouchOutside(false); 42 | progressDialog.show(); 43 | 44 | } 45 | 46 | public void btnStop(View view) { 47 | startActivity(new Intent(this, TestActivity.class)); 48 | } 49 | 50 | public void btnInter(View view) { 51 | if (System.currentTimeMillis() - lastClickTime >= FAST_CLICK_DELAY_TIME) { 52 | lastClickTime = System.currentTimeMillis(); 53 | } 54 | } 55 | 56 | @SingleClick(2000) 57 | public void btnAop(View view) { 58 | ToastUtils.showShort("btnAop"); 59 | Log.e(TAG, "btnAop"); 60 | } 61 | 62 | public void btnKotlin(View view) { 63 | startActivity(new Intent(this,MainActivity.class)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/zj/it/bhne/androidaop/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package zj.it.bhne.androidaop 2 | 3 | import android.os.Bundle 4 | 5 | import android.util.Log 6 | import android.view.View 7 | import androidx.appcompat.app.AppCompatActivity 8 | import com.blankj.utilcode.util.ToastUtils 9 | import com.zj.singclick.SingleClick 10 | import com.zj.singclick.click 11 | import com.zj.singclick.setSafeListener 12 | import kotlinx.android.synthetic.main.activity_main.* 13 | 14 | class MainActivity : AppCompatActivity() ,View.OnClickListener{ 15 | 16 | 17 | override fun onCreate(savedInstanceState: Bundle?){ 18 | super.onCreate(savedInstanceState) 19 | setContentView(R.layout.activity_main) 20 | btnClick.setOnClickListener(this) 21 | initView() 22 | } 23 | 24 | private fun initView() { 25 | btnKuoZhan.setSafeListener { 26 | ToastUtils.showShort("222") 27 | Log.e("kuozhan","wwww") 28 | } 29 | 30 | btnKuoZhanClick.click { 31 | ToastUtils.showShort("ss") 32 | Log.e("kuozhan","呵呵呵") 33 | } 34 | } 35 | 36 | 37 | @SingleClick 38 | override fun onClick(v: View?) { 39 | if (v != null) { 40 | when(v.id){ 41 | R.id.btnClick->{ 42 | ToastUtils.showShort("哈哈哈") 43 | Log.e("ee","wwww") 44 | } 45 | } 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/zj/it/bhne/androidaop/OnClick.kt: -------------------------------------------------------------------------------- 1 | package zj.it.bhne.androidaop 2 | 3 | import android.view.View 4 | 5 | /** 6 | * 版权:渤海新能 版权所有 7 | * @author zhujiang 8 | * 版本:1.5 9 | * 创建日期:2020/4/29 10 | * 描述:AndroidAOP 11 | * 12 | */ 13 | 14 | //inline fun View.setSafeListener(crossinline action:()->Unit){ 15 | // var lastClick=0L 16 | // setOnClickListener { 17 | // val gap = System.currentTimeMillis() - lastClick 18 | // lastClick=System.currentTimeMillis() 19 | // if(gap<1500) return@setOnClickListener 20 | // action.invoke() 21 | // } 22 | //} 23 | // 24 | // 25 | //var _viewClickFlag = false 26 | //var _clickRunnable = Runnable { _viewClickFlag = false } 27 | //fun View.click(action: (view: View) -> Unit) { 28 | // setOnClickListener { 29 | // if (!_viewClickFlag) { 30 | // _viewClickFlag = true 31 | // action(it) 32 | // } 33 | // removeCallbacks(_clickRunnable) 34 | // postDelayed(_clickRunnable, 1000) 35 | // } 36 | //} -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 |