一.前言:AOP(Aspect Orented Programming):面向切面编程,通过ajc编译器把java文件编译为加工过的class文件,个人感觉就是定点插入代码。
二.应用场景:权限申请,日志统计,行为统计,性能检测。
三.项目配置:这里我放在公共模块中
(1)project中添加:
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4'
(2)主module中
apply plugin: 'com.hujiang.android-aspectjx'
***
implementation 'org.aspectj:aspectjrt:1.8.13'
(3)common module中
apply plugin: 'com.hujiang.android-aspectjx'
***
api 'org.aspectj:aspectjrt:1.8.13'
四.简单例子一:按钮两秒内不可再按
(1)声明注解类:
package aop
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class AopOnclick (val value:Long = 2000){
}
(2)功能类:
package aop
import android.os.SystemClock
/*
两次间隔是否超过规定时间
*/
object AopClickUtil {
private var mLastClickTime:Long = 0
fun isFastDoubleClick(intervalMillis:Long):Boolean{
val time = SystemClock.elapsedRealtime()
val tiemInterval = Math.abs(time- mLastClickTime)
return if(tiemInterval<intervalMillis){
true
}else{
mLastClickTime = time
false
}
}
}
(3) 切面类:
@Aspect
class AopClickAspect{
/*
定义入口 @注解 访问权限 返回值类型 类名.函数名(参数)
*/
@Pointcut("execution(@aop.AopOnclick * *(..))")
fun methodAnnotated(){
}
@Around("methodAnnotated()")
@Throws(Throwable::class)
fun aroundJoinPoint(joinPoint: ProceedingJoinPoint){
val methodSignature = joinPoint.signature as MethodSignature
val method = methodSignature.method
//判断此方法是否有AopOnclick注解
if(!method.isAnnotationPresent(AopOnclick::class.java)){
return
}
Log.d("aspect","method name:"+method.name)
val aopOnclick = method.getAnnotation(AopOnclick::class.java)
if(!AopClickUtil.isFastDoubleClick(aopOnclick.value)){
joinPoint.proceed()
}
}
}
(4)使用
login_ID.setOnClickListener(object :View.OnClickListener{
@AopOnclick
override fun onClick(v: View?) {
//do something
}
})
五 权限控制框架例子。
(1)权限反馈接口
interface IPermission {
fun onPermissionGranted()
fun onPermissionDefied(requestCode:Int)
fun onPermissionCanceled(requestCode: Int)
}
(2)注解类
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class PermissionNeed( val permissions: Array<String>,val requestCode:Int = 0) {
}
(3)权限展示透明activity类
class PermissionActivity : Activity() {
var mRequestCode:Int? = 0
companion object{
val PERMISSION:String = "permission"
val REQUESTCODE:String = "requestCode"
private var mIPermission:IPermission? = null
fun startPermissionRequest(context: Context,permissions: Array<String>,requestCode:Int,iPermission: IPermission){
mIPermission = iPermission
var intent = Intent(context,PermissionActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
var bundle = Bundle()
bundle.putStringArray(PERMISSION,permissions)
bundle.putInt(REQUESTCODE,requestCode)
intent.putExtras(bundle)
context.startActivity(intent)
if(context is Activity){
(context as Activity).overridePendingTransition(0,0)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var bundle = intent.extras
var permissions = bundle?.getStringArray(PERMISSION)
mRequestCode = bundle?.getInt(REQUESTCODE)
requestPermission(permissions,mRequestCode)
}
private fun requestPermission(permissions: Array<String>?, requestCode: Int?) {
/*
权限通过
*/
if(hasSelfPermission(permissions!!)){
mIPermission?.onPermissionGranted()
finish()
} else{
ActivityCompat.requestPermissions(this,permissions!!,requestCode!!)
for (item in permissions){
Log.d("permission",item+"\n")
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(mRequestCode==requestCode) {
if (verifyPermission(grantResults)) {
mIPermission?.onPermissionGranted()
} else {
if (shouldShoeRequestPermissionRationale(permissions!!)) {
mIPermission?.onPermissionCanceled(requestCode)
//
} else {
mIPermission?.onPermissionDefied(requestCode)
}
}
finish()
overridePendingTransition(0, 0)
}
}
fun hasSelfPermission(permissions: Array<String>):Boolean{
for (item in permissions){
if(ContextCompat.checkSelfPermission(this,item)!=PackageManager.PERMISSION_GRANTED){
return false
}
}
return true
}
fun verifyPermission(grantResults: IntArray):Boolean{
if(grantResults.size==0) return false
for(item in grantResults){
if(item!=PackageManager.PERMISSION_GRANTED){
return false
}
}
return true
}
fun shouldShoeRequestPermissionRationale(permissions: Array< out String>):Boolean {
for(item in permissions){
if(ActivityCompat.shouldShowRequestPermissionRationale(this,item)){
return true
}
}
return false
}
}
注册:此activity
<activity android:name="permission.PermissionActivity"
android:theme="@style/translucent"
/>
style:
<style name="translucent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
</style>
(4)切面类
@Aspect
class PermissionAspect {
@Pointcut("execution(@permission.PermissionNeed * *(..)) && @annotation(permissionNeed)")
fun requestPermission(permissionNeed:PermissionNeed){}
@Around("requestPermission(permissionNeed)")
fun aroundJoinPoint(joinPoint: ProceedingJoinPoint,permissionNeed:PermissionNeed){
var obj = joinPoint.`this`
var context:Context = obj as Context
PermissionActivity.startPermissionRequest(context,permissionNeed.permissions,
permissionNeed.requestCode,object:IPermission{
override fun onPermissionGranted() {
//通过了则调用对应被注解的方法
joinPoint.proceed()
Log.d("permission","Granted:")
}
override fun onPermissionDefied(requestCode: Int) {
Log.d("permission","defied:"+requestCode.toString())
}
override fun onPermissionCanceled(requestCode: Int) {
Log.d("permission","canceled:"+requestCode.toString())
}
})
}
}
(5)调用:在所需的类中
@PermissionNeed(permissions = arrayOf(
Permission.WRITE_EXTERNAL_STORAGE
, Permission.READ_PHONE_STATE
,android.Manifest.permission.ACCESS_NOTIFICATION_POLICY
,android.Manifest.permission.INTERNET
,android.Manifest.permission.ACCESS_WIFI_STATE
,android.Manifest.permission.ACCESS_NETWORK_STATE
,android.Manifest.permission.WRITE_EXTERNAL_STORAGE
),requestCode = 101)
private fun requestBasePermission(){
//do something
}
这样只要调用requestBasePermission()方法就会申请权限(如果没申请或者申请没有过),这里的权限拒绝和权限拒绝不再询问没有处理,可以自个加。
本文介绍了在Kotlin中如何使用AOP进行面向切面编程,包括其概念、应用场景,如权限申请、日志统计等,并提供了一个简单的按钮双击防护的示例及一个权限控制框架的实现,详细讲解了注解、切面类和功能类的使用。
1725

被折叠的 条评论
为什么被折叠?



