请提供构建环境相关信息:
发送构建错误时,请先确定是构建错误还是aspectj织入错误:
已自查,并没有找到对应的记录
- 如果是aspectj织入发生异常,会在对应
module下的build/tmp/transformClassesWithAjxForXXX/logs目录下产生ajcore为前缀的日志文件,请提供该日志文件以便查找问题
非编译时的问题,而是运行时的问题
W/System.err: java.util.EmptyStackException
W/System.err: at java.util.Stack.peek(Stack.java:102)
W/System.err: at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:170)
W/System.err: at com.hjq.demo.aop.PermissionsAspect$1.onGranted(PermissionsAspect.java:78)
W/System.err: at com.hjq.demo.other.PermissionInterceptor.grantedPermissionRequest(PermissionInterceptor.java:123)
W/System.err: at com.hjq.permissions.PermissionFragment.onRequestPermissionsResult(PermissionFragment.java:394)
W/System.err: at android.app.Activity.dispatchRequestPermissionsResultToFragment(Activity.java:7626)
W/System.err: at android.app.Activity.dispatchActivityResult(Activity.java:7470)
W/System.err: at android.app.ActivityThread.deliverResults(ActivityThread.java:4391)
W/System.err: at android.app.ActivityThread.handleSendResult(ActivityThread.java:4440)
W/System.err: at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
W/System.err: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
W/System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err: at android.os.Looper.loop(Looper.java:193)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6718)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
@Aspect
public class PermissionsAspect {
/**
* 方法切入点
*/
@Pointcut("execution(@com.hjq.demo.aop.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()) {
activity = ActivityManager.getInstance().getTopActivity();
}
if (activity == null || activity.isFinishing() || activity.isDestroyed()) {
Timber.e("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) {
XXPermissions.with(activity)
.permission(permissions)
.interceptor(new PermissionInterceptor())
.request(new OnPermissionCallback() {
@Override
public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
if (allGranted) {
try {
// 获得权限,执行原方法
joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
CrashReport.postCatchedException(e);
}
}
}
});
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Permissions {
/**
* 需要申请权限的集合
*/
String[] value();
}
@Aspect
public class LogAspect {
/**
* 构造方法切入点
*/
@Pointcut("execution(@com.hjq.demo.aop.Log *.new(..))")
public void constructor() {}
/**
* 方法切入点
*/
@Pointcut("execution(@com.hjq.demo.aop.Log * *(..))")
public void method() {}
/**
* 在连接点进行方法替换
*/
@Around("(method() || constructor()) && @annotation(log)")
public Object aroundJoinPoint(ProceedingJoinPoint joinPoint, Log 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, Log 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, Log 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) {
Timber.tag(tag);
Timber.d(msg);
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface Log {
String value() default "AOPLog";
}
public final class ImageSelectActivity extends AppActivity {
.....
@Log
@Permissions({Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE})
public static void start(BaseActivity activity, int maxSelect, OnPhotoSelectListener listener) {
.....
}
.....
}
我在某个方法上面加了两个 AOP 注解,一个是打印方法名及参数的 Log 的 AOP 注解,另外一个是请求权限的 AOP 注解,现在出现了一种情况,权限回调中有正常调用 joinPoint.proceed(),但是会出现 java.util.EmptyStackException 异常,最终导致切面无法往下执行。
我如果删掉 Log AOP 注解,则就没有异常了。又或者权限是授予状态,也是没有问题的,因为调用 XXPermissions 申请权限的时候,它会先判断授权有没有授予,有的话会直接回调授予的方法(同步操作),如果没有授予权限的话,则会开启一个透明的 Fragment 来发起申请权限(异步操作),可能是因为这个原因不行的,但是权限框架这样做是没有问题的。
之前使用 HujiangTechnology/gradle_plugin_android_aspectjx 是没有问题的,现在换成了 wurensen/gradle_plugin_android_aspectjx 就报这个错了,劳烦大大有空看一下
请提供构建环境相关信息:
当前使用的插件版本:3.3.1
AGP(Android Gradle Plugin)版本:7.1.0
Gradle版本:7.2-all.zip
发送构建错误时,请先确定是构建错误还是aspectj织入错误:
module下的build/tmp/transformClassesWithAjxForXXX/logs目录下产生ajcore为前缀的日志文件,请提供该日志文件以便查找问题