All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.flyjingfish.android_aop_annotation.AopMethod Maven / Gradle / Ivy

package com.flyjingfish.android_aop_annotation;

import androidx.annotation.RequiresApi;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * 此类持有执行方法的反射信息,且进行过缓存了,可放心使用
 */
public final class AopMethod {
    private final Method targetMethod;
    private final boolean isSuspend;
    private final Object suspendContinuation;

    private final String[] mParamNames;
    private final Class mReturnType;
    private final Class[] mParamClasses;

    AopMethod(Method targetMethod, boolean isSuspend, Object suspendContinuation, String[] paramNames,Class[] paramClasses,Class returnType) {
        this.targetMethod = targetMethod;
        this.isSuspend = isSuspend;
        this.suspendContinuation = suspendContinuation;
        this.mParamNames = paramNames;
        this.mParamClasses = paramClasses;
        this.mReturnType = returnType;
    }

    public String getName() {
        return targetMethod.getName();
    }

    public String[] getParameterNames() {
        if (isSuspend && mParamNames.length > 0){
            String[] newNames = new String[mParamNames.length - 1];
            System.arraycopy(mParamNames, 0, newNames, 0, newNames.length);
            return newNames;
        }

        return mParamNames;
    }

    /**
     *
     * @return 如果切点函数是 suspend 函数并且返回类型是基本数据类型,会自动转化为包装类型
     */
    public Class getReturnType() {
        if (mReturnType != null){
            return mReturnType;
        }
        return targetMethod.getReturnType();
    }

    public Type getGenericReturnType() {
        if (isSuspend){
            Type[] types = targetMethod.getGenericParameterTypes();
            Type types1 = types[types.length-1];
            if (types1 instanceof ParameterizedType){
                Type[] realTypes = ((ParameterizedType) types1).getActualTypeArguments();
                if (realTypes.length > 0) {
                    Type continuationType = realTypes[0];
                    try {
                        Field field = continuationType.getClass().getDeclaredField("superBound");
                        field.setAccessible(true);
                        Object superBoundObj = field.get(continuationType);
                        Field typesField= superBoundObj.getClass().getDeclaredField("types");
                        typesField.setAccessible(true);
                        List typesList= (List) typesField.get(superBoundObj);
                        return typesList.get(0);
                    } catch (Throwable e) {
                    }
                }
            }
        }
        return targetMethod.getGenericReturnType();
    }

    public Class getDeclaringClass() {
        return targetMethod.getDeclaringClass();
    }

    public Class[] getParameterTypes() {
        Class[] cls;
        if (mParamClasses != null){
            cls = mParamClasses;
        }else {
            cls = targetMethod.getParameterTypes();
        }
        if (isSuspend){
            Class[] newCls = new Class[cls.length - 1];
            System.arraycopy(cls, 0, newCls, 0, newCls.length);
            return newCls;
        }

        return cls;
    }

    public Type[] getGenericParameterTypes() {
        Type[] types = targetMethod.getGenericParameterTypes();
        if (isSuspend){
            Type[] newTypes = new Class[types.length - 1];
            System.arraycopy(types, 0, newTypes, 0, newTypes.length);
            return newTypes;
        }
        return types;
    }

    public int getModifiers() {
        return targetMethod.getModifiers();
    }

    public Annotation[] getAnnotations() {
        return targetMethod.getAnnotations();
    }

    public  T getAnnotation(Class var1) {
        return targetMethod.getAnnotation(var1);
    }
    @RequiresApi(api = 26)
    public Parameter[] getParameters() {
        Parameter[] parameters = targetMethod.getParameters();
        if (isSuspend && parameters.length > 0){
            Parameter[] newParameters = new Parameter[parameters.length - 1];
            System.arraycopy(parameters, 0, newParameters, 0, newParameters.length);
            return newParameters;
        }
        return parameters;
    }
    public Annotation[][] getParameterAnnotations() {
        Annotation[][] parameterAnnotations = targetMethod.getParameterAnnotations();
        if (isSuspend && parameterAnnotations.length > 0){
            Annotation[][] newParameterAnnotations = new Annotation[parameterAnnotations.length - 1][];
            System.arraycopy(parameterAnnotations, 0, newParameterAnnotations, 0, newParameterAnnotations.length);
            return newParameterAnnotations;
        }
        return parameterAnnotations;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy