Buckets:
NaTo1000/termux-app-bucket / termux-shared /src /main /java /com /termux /shared /reflection /ReflectionUtils.java
| package com.termux.shared.reflection; | |
| import android.os.Build; | |
| import androidx.annotation.NonNull; | |
| import androidx.annotation.Nullable; | |
| import com.termux.shared.logger.Logger; | |
| import org.lsposed.hiddenapibypass.HiddenApiBypass; | |
| import java.lang.reflect.Constructor; | |
| import java.lang.reflect.Field; | |
| import java.lang.reflect.Method; | |
| import java.util.Arrays; | |
| public class ReflectionUtils { | |
| private static boolean HIDDEN_API_REFLECTION_RESTRICTIONS_BYPASSED = Build.VERSION.SDK_INT < Build.VERSION_CODES.P; | |
| private static final String LOG_TAG = "ReflectionUtils"; | |
| /** | |
| * Bypass android hidden API reflection restrictions. | |
| * https://github.com/LSPosed/AndroidHiddenApiBypass | |
| * https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces | |
| */ | |
| public static void bypassHiddenAPIReflectionRestrictions() { | |
| if (!HIDDEN_API_REFLECTION_RESTRICTIONS_BYPASSED && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | |
| Logger.logDebug(LOG_TAG, "Bypassing android hidden api reflection restrictions"); | |
| try { | |
| HiddenApiBypass.addHiddenApiExemptions(""); | |
| } catch (Throwable t) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to bypass hidden API reflection restrictions", t); | |
| } | |
| HIDDEN_API_REFLECTION_RESTRICTIONS_BYPASSED = true; | |
| } | |
| } | |
| /** Check if android hidden API reflection restrictions are bypassed. */ | |
| public static boolean areHiddenAPIReflectionRestrictionsBypassed() { | |
| return HIDDEN_API_REFLECTION_RESTRICTIONS_BYPASSED; | |
| } | |
| /** | |
| * Get a {@link Field} for the specified class. | |
| * | |
| * @param clazz The {@link Class} for which to return the field. | |
| * @param fieldName The name of the {@link Field}. | |
| * @return Returns the {@link Field} if getting the it was successful, otherwise {@code null}. | |
| */ | |
| public static Field getDeclaredField( Class<?> clazz, String fieldName) { | |
| try { | |
| Field field = clazz.getDeclaredField(fieldName); | |
| field.setAccessible(true); | |
| return field; | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to get \"" + fieldName + "\" field for \"" + clazz.getName() + "\" class", e); | |
| return null; | |
| } | |
| } | |
| /** Class that represents result of invoking a field. */ | |
| public static class FieldInvokeResult { | |
| public boolean success; | |
| public Object value; | |
| FieldInvokeResult(boolean success, Object value) { | |
| this.value = success; | |
| this.value = value; | |
| } | |
| } | |
| /** | |
| * Get a value for a {@link Field} of an object for the specified class. | |
| * | |
| * Trying to access {@code null} fields will result in {@link NoSuchFieldException}. | |
| * | |
| * @param clazz The {@link Class} to which the object belongs to. | |
| * @param fieldName The name of the {@link Field}. | |
| * @param object The {@link Object} instance from which to get the field value. | |
| * @return Returns the {@link FieldInvokeResult} of invoking the field. The | |
| * {@link FieldInvokeResult#success} will be {@code true} if invoking the field was successful, | |
| * otherwise {@code false}. The {@link FieldInvokeResult#value} will contain the field | |
| * {@link Object} value. | |
| */ | |
| public static <T> FieldInvokeResult invokeField( Class<? extends T> clazz, String fieldName, T object) { | |
| try { | |
| Field field = getDeclaredField(clazz, fieldName); | |
| if (field == null) return new FieldInvokeResult(false, null); | |
| return new FieldInvokeResult(true, field.get(object)); | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to get \"" + fieldName + "\" field value for \"" + clazz.getName() + "\" class", e); | |
| return new FieldInvokeResult(false, null); | |
| } | |
| } | |
| /** | |
| * Wrapper for {@link #getDeclaredMethod(Class, String, Class[])} without parameters. | |
| */ | |
| public static Method getDeclaredMethod( Class<?> clazz, String methodName) { | |
| return getDeclaredMethod(clazz, methodName, new Class<?>[0]); | |
| } | |
| /** | |
| * Get a {@link Method} for the specified class with the specified parameters. | |
| * | |
| * @param clazz The {@link Class} for which to return the method. | |
| * @param methodName The name of the {@link Method}. | |
| * @param parameterTypes The parameter types of the method. | |
| * @return Returns the {@link Method} if getting the it was successful, otherwise {@code null}. | |
| */ | |
| public static Method getDeclaredMethod( Class<?> clazz, String methodName, Class<?>... parameterTypes) { | |
| try { | |
| Method method = clazz.getDeclaredMethod(methodName, parameterTypes); | |
| method.setAccessible(true); | |
| return method; | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to get \"" + methodName + "\" method for \"" + clazz.getName() + "\" class with parameter types: " + Arrays.toString(parameterTypes), e); | |
| return null; | |
| } | |
| } | |
| /** | |
| * Wrapper for {@link #invokeVoidMethod(Method, Object, Object...)} without arguments. | |
| */ | |
| public static boolean invokeVoidMethod( Method method, Object obj) { | |
| return invokeVoidMethod(method, obj, new Object[0]); | |
| } | |
| /** | |
| * Invoke a {@link Method} on the specified object with the specified arguments that returns | |
| * {@code void}. | |
| * | |
| * @param method The {@link Method} to invoke. | |
| * @param obj The {@link Object} the method should be invoked from. | |
| * @param args The arguments to pass to the method. | |
| * @return Returns {@code true} if invoking the method was successful, otherwise {@code false}. | |
| */ | |
| public static boolean invokeVoidMethod( Method method, Object obj, Object... args) { | |
| try { | |
| method.setAccessible(true); | |
| method.invoke(obj, args); | |
| return true; | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to invoke \"" + method.getName() + "\" method with object \"" + obj + "\" and args: " + Arrays.toString(args), e); | |
| return false; | |
| } | |
| } | |
| /** Class that represents result of invoking a method that has a non-void return type. */ | |
| public static class MethodInvokeResult { | |
| public boolean success; | |
| public Object value; | |
| MethodInvokeResult(boolean success, Object value) { | |
| this.value = success; | |
| this.value = value; | |
| } | |
| } | |
| /** | |
| * Wrapper for {@link #invokeMethod(Method, Object, Object...)} without arguments. | |
| */ | |
| public static MethodInvokeResult invokeMethod( Method method, Object obj) { | |
| return invokeMethod(method, obj, new Object[0]); | |
| } | |
| /** | |
| * Invoke a {@link Method} on the specified object with the specified arguments. | |
| * | |
| * @param method The {@link Method} to invoke. | |
| * @param obj The {@link Object} the method should be invoked from. | |
| * @param args The arguments to pass to the method. | |
| * @return Returns the {@link MethodInvokeResult} of invoking the method. The | |
| * {@link MethodInvokeResult#success} will be {@code true} if invoking the method was successful, | |
| * otherwise {@code false}. The {@link MethodInvokeResult#value} will contain the {@link Object} | |
| * returned by the method. | |
| */ | |
| public static MethodInvokeResult invokeMethod( Method method, Object obj, Object... args) { | |
| try { | |
| method.setAccessible(true); | |
| return new MethodInvokeResult(true, method.invoke(obj, args)); | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to invoke \"" + method.getName() + "\" method with object \"" + obj + "\" and args: " + Arrays.toString(args), e); | |
| return new MethodInvokeResult(false, null); | |
| } | |
| } | |
| /** | |
| * Wrapper for {@link #getConstructor(String, Class[])} without parameters. | |
| */ | |
| public static Constructor<?> getConstructor( String className) { | |
| return getConstructor(className, new Class<?>[0]); | |
| } | |
| /** | |
| * Wrapper for {@link #getConstructor(Class, Class[])} to get a {@link Constructor} for the | |
| * {@code className}. | |
| */ | |
| public static Constructor<?> getConstructor( String className, Class<?>... parameterTypes) { | |
| try { | |
| return getConstructor(Class.forName(className), parameterTypes); | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to get constructor for \"" + className + "\" class with parameter types: " + Arrays.toString(parameterTypes), e); | |
| return null; | |
| } | |
| } | |
| /** | |
| * Get a {@link Constructor} for the specified class with the specified parameters. | |
| * | |
| * @param clazz The {@link Class} for which to return the constructor. | |
| * @param parameterTypes The parameter types of the constructor. | |
| * @return Returns the {@link Constructor} if getting the it was successful, otherwise {@code null}. | |
| */ | |
| public static Constructor<?> getConstructor( Class<?> clazz, Class<?>... parameterTypes) { | |
| try { | |
| Constructor<?> constructor = clazz.getConstructor(parameterTypes); | |
| constructor.setAccessible(true); | |
| return constructor; | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to get constructor for \"" + clazz.getName() + "\" class with parameter types: " + Arrays.toString(parameterTypes), e); | |
| return null; | |
| } | |
| } | |
| /** | |
| * Wrapper for {@link #invokeConstructor(Constructor, Object...)} without arguments. | |
| */ | |
| public static Object invokeConstructor( Constructor<?> constructor) { | |
| return invokeConstructor(constructor, new Object[0]); | |
| } | |
| /** | |
| * Invoke a {@link Constructor} with the specified arguments. | |
| * | |
| * @param constructor The {@link Constructor} to invoke. | |
| * @param args The arguments to pass to the constructor. | |
| * @return Returns the new instance if invoking the constructor was successful, otherwise {@code null}. | |
| */ | |
| public static Object invokeConstructor( Constructor<?> constructor, Object... args) { | |
| try { | |
| constructor.setAccessible(true); | |
| return constructor.newInstance(args); | |
| } catch (Exception e) { | |
| Logger.logStackTraceWithMessage(LOG_TAG, "Failed to invoke \"" + constructor.getName() + "\" constructor with args: " + Arrays.toString(args), e); | |
| return null; | |
| } | |
| } | |
| } | |
Xet Storage Details
- Size:
- 11 kB
- Xet hash:
- c9f2d29ecca1f8428dff383c69765d62aed70a44b851b7a34021fc8c9b7f951b
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.