forked from HujiangTechnology/gradle_plugin_android_aspectjx
-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #61 from wurensen/hotfix/3.3.2
Hotfix/3.3.2
- Loading branch information
Showing
12 changed files
with
314 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.lancewu.aspectj | ||
|
||
/** | ||
* Created by LanceWu on 2022/12/19 | ||
* | ||
* 注解测试 | ||
*/ | ||
@Retention(AnnotationRetention.RUNTIME) | ||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) | ||
annotation class AOPLog(val value: String = "AOPLog") | ||
|
||
@Retention(AnnotationRetention.RUNTIME) | ||
@Target(AnnotationTarget.FUNCTION) | ||
annotation class Permissions(val value: Array<String>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package com.lancewu.aspectj; | ||
|
||
import android.os.Looper; | ||
import android.os.Trace; | ||
import android.util.Log; | ||
|
||
import androidx.annotation.NonNull; | ||
|
||
import org.aspectj.lang.ProceedingJoinPoint; | ||
import org.aspectj.lang.Signature; | ||
import org.aspectj.lang.annotation.Around; | ||
import org.aspectj.lang.annotation.Aspect; | ||
import org.aspectj.lang.annotation.Pointcut; | ||
import org.aspectj.lang.reflect.CodeSignature; | ||
import org.aspectj.lang.reflect.MethodSignature; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* Created by LanceWu on 2022/12/19.<br> | ||
* TODO 类说明 | ||
*/ | ||
@Aspect | ||
public class LogAspect { | ||
|
||
/** | ||
* 构造方法切入点 | ||
*/ | ||
@Pointcut("execution(@com.lancewu.aspectj.AOPLog *.new(..))") | ||
public void constructor() { | ||
} | ||
|
||
/** | ||
* 方法切入点 | ||
*/ | ||
@Pointcut("execution(@com.lancewu.aspectj.AOPLog * *(..))") | ||
public void method() { | ||
} | ||
|
||
/** | ||
* 在连接点进行方法替换 | ||
*/ | ||
@Around("(method() || constructor()) && @annotation(log)") | ||
public Object aroundJoinPoint(ProceedingJoinPoint joinPoint, AOPLog log) throws Throwable { | ||
enterMethod(joinPoint, log); | ||
|
||
long startNanos = System.nanoTime(); | ||
Object result = joinPoint.proceed(); | ||
long stopNanos = System.nanoTime(); | ||
|
||
exitMethod(joinPoint, log, result, TimeUnit.NANOSECONDS.toMillis(stopNanos - startNanos)); | ||
|
||
return result; | ||
} | ||
|
||
/** | ||
* 方法执行前切入 | ||
*/ | ||
private void enterMethod(ProceedingJoinPoint joinPoint, AOPLog log) { | ||
CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature(); | ||
|
||
// 方法所在类 | ||
String className = codeSignature.getDeclaringType().getName(); | ||
// 方法名 | ||
String methodName = codeSignature.getName(); | ||
// 方法参数名集合 | ||
String[] parameterNames = codeSignature.getParameterNames(); | ||
// 方法参数值集合 | ||
Object[] parameterValues = joinPoint.getArgs(); | ||
|
||
//记录并打印方法的信息 | ||
StringBuilder builder = getMethodLogInfo(className, methodName, parameterNames, parameterValues); | ||
|
||
log(log.value(), builder.toString()); | ||
|
||
final String section = builder.substring(2); | ||
Trace.beginSection(section); | ||
} | ||
|
||
/** | ||
* 获取方法的日志信息 | ||
* | ||
* @param className 类名 | ||
* @param methodName 方法名 | ||
* @param parameterNames 方法参数名集合 | ||
* @param parameterValues 方法参数值集合 | ||
*/ | ||
@NonNull | ||
private StringBuilder getMethodLogInfo(String className, String methodName, String[] parameterNames, Object[] parameterValues) { | ||
StringBuilder builder = new StringBuilder("\u21E2 "); | ||
builder.append(className) | ||
.append(".") | ||
.append(methodName) | ||
.append('('); | ||
for (int i = 0; i < parameterValues.length; i++) { | ||
if (i > 0) { | ||
builder.append(", "); | ||
} | ||
builder.append(parameterNames[i]).append('='); | ||
builder.append(parameterValues[i]); | ||
} | ||
builder.append(')'); | ||
|
||
if (Looper.myLooper() != Looper.getMainLooper()) { | ||
builder.append(" [Thread:\"").append(Thread.currentThread().getName()).append("\"]"); | ||
} | ||
return builder; | ||
} | ||
|
||
/** | ||
* 方法执行完毕,切出 | ||
* | ||
* @param result 方法执行后的结果 | ||
* @param lengthMillis 执行方法所需要的时间 | ||
*/ | ||
private void exitMethod(ProceedingJoinPoint joinPoint, AOPLog log, Object result, long lengthMillis) { | ||
Trace.endSection(); | ||
|
||
Signature signature = joinPoint.getSignature(); | ||
|
||
String className = signature.getDeclaringType().getName(); | ||
String methodName = signature.getName(); | ||
|
||
StringBuilder builder = new StringBuilder("\u21E0 ") | ||
.append(className) | ||
.append(".") | ||
.append(methodName) | ||
.append(" [") | ||
.append(lengthMillis) | ||
.append("ms]"); | ||
|
||
// 判断方法是否有返回值 | ||
if (signature instanceof MethodSignature && ((MethodSignature) signature).getReturnType() != void.class) { | ||
builder.append(" = "); | ||
builder.append(result.toString()); | ||
} | ||
|
||
log(log.value(), builder.toString()); | ||
} | ||
|
||
private void log(String tag, String msg) { | ||
Log.d(tag, msg); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
app/src/main/java/com/lancewu/aspectj/PermissionsAspect.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.lancewu.aspectj; | ||
|
||
import android.app.Activity; | ||
import android.content.DialogInterface; | ||
import android.util.Log; | ||
|
||
import androidx.appcompat.app.AlertDialog; | ||
|
||
import org.aspectj.lang.ProceedingJoinPoint; | ||
import org.aspectj.lang.annotation.Around; | ||
import org.aspectj.lang.annotation.Aspect; | ||
import org.aspectj.lang.annotation.Pointcut; | ||
|
||
import java.util.Arrays; | ||
|
||
/** | ||
* Created by LanceWu on 2022/12/19.<br> | ||
* TODO 类说明 | ||
*/ | ||
@Aspect | ||
public class PermissionsAspect { | ||
|
||
/** | ||
* 方法切入点 | ||
*/ | ||
@Pointcut("execution(@com.lancewu.aspectj.Permissions * *(..))") | ||
public void method() { | ||
} | ||
|
||
/** | ||
* 在连接点进行方法替换 | ||
*/ | ||
@Around("method() && @annotation(permissions)") | ||
public void aroundJoinPoint(ProceedingJoinPoint joinPoint, Permissions permissions) { | ||
Activity activity = null; | ||
|
||
// 方法参数值集合 | ||
Object[] parameterValues = joinPoint.getArgs(); | ||
for (Object arg : parameterValues) { | ||
if (!(arg instanceof Activity)) { | ||
continue; | ||
} | ||
activity = (Activity) arg; | ||
break; | ||
} | ||
|
||
if (activity == null || activity.isFinishing() || activity.isDestroyed()) { | ||
Log.e("PermissionsAspect", "The activity has been destroyed and permission requests cannot be made"); | ||
return; | ||
} | ||
|
||
requestPermissions(joinPoint, activity, permissions.value()); | ||
} | ||
|
||
private void requestPermissions(ProceedingJoinPoint joinPoint, Activity activity, String[] permissions) { | ||
Log.d("PermissionsAspect", "申请权限:" + Arrays.toString(permissions)); | ||
// FIXME: 2022/12/20 嵌套around-advice时,采用延期调用或是中断-恢复的方式,来调用joinPoint.proceed(), | ||
// 会出现EmptyStackException异常,原因是aspectj设计上,对于嵌套的around-advice,采取栈的方式存储; | ||
// 相关问题可参照:https://github.com/eclipse/org.aspectj/issues/128 | ||
// 该issues是多线程调用,在1.9.9版本已修复,但类似以下的使用方式不符合设计 | ||
new AlertDialog.Builder(activity) | ||
.setCancelable(false) | ||
.setMessage("模拟申请权限弹窗") | ||
.setPositiveButton("点击模拟获取权限结果", new DialogInterface.OnClickListener() { | ||
@Override | ||
public void onClick(DialogInterface dialog, int which) { | ||
Log.d("PermissionsAspect", "模拟申请权限结束"); | ||
// 获得权限,执行原方法 | ||
try { | ||
joinPoint.proceed(); | ||
} catch (Throwable e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
}) | ||
.show(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.