1. Background
In andorid development, it is often encountered that when there is no Context context object in some tool classes, some system service proxy objects cannot be created. For example, classes under the source code (framework/base/graphics/java/android/graphics) path have no context object. At that time, I needed to call the AMS API to obtain the name of the current interface activity as a judgment condition to modify the parameters in these tool classes, but there are no context objects in these tool classes. What should I do?
Generally speaking, the method to obtain the top-level activity name is as follows:
//1. Get the AMS proxy object ActivityManagerActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); //2. Call the relevant API to get the name of the top-level activityString activityName = (1).get(0).();
The above code is obtained directly when there is a context object context.
And in the above-mentioned categories, there is no context at all, so how to do it? At this time, we implement it through Java reflection. Next, this article will explain the Java reflection mechanism and use reflection to obtain the top-level activity.
2. Java reflection
2.1 What is reflection
Reflection is the self-analysis ability of a program. Through reflection, you can determine which methods are in the class, which construct methods are there and which member variables are there. In the running state, for any class, you can know all the properties and methods of this class; for any object, you can call any methods and properties of it; this function of dynamically obtaining information and dynamically calling object methods is called the reflection mechanism of the Java language.
2.2 Under what circumstances should we use reflection
First of all, java is object-oriented and everything is an object. When we get this class object, we can access the member variables in the class and call the methods in the class. But what? For private variables and methods, its access permission scope is only in this class. In external or inherited classes, even if you create an object of this class, it cannot be called directly. Let’s take a look at this example:
An ordinary User class
public class User { private String name = "Mozi"; //Private variable public int age = 18; //Private method private int test() { ("Private Member Method"); return 1; } protected String test2() { ("protected member method"); return "protected"; } public static void main(String[] args) { //If an object is created in this class, all methods and variables can be accessed directly User user = new User(); (); //Access private variables (());//Calling private method } }
The printing results are as follows:
Mozi
Private member method
1
If you create this class object inside the outside, can you still directly access private methods and variables? Test it out:
public class PrivateTest { public static void main(String[] args) { User user = new User(); //The object created in the outside directly has a private variable and an error is reported //(); // Objects created inside the outside call the private method directly, and an error is also reported //(()); //But you can directly access protected public methods and variables (); (user.test2()); } }
The two lines of code that reported an error have been commented out, and you can copy the code to verify it.
Of course, in andorid development, there are other scenarios that use reflection. Many classes or methods often add "@hide" annotation mark. These APIs are not allowed to be called directly in third-party applications. For example, the SystemProperties class is under, but this class is hidden. Apps without system permissions (android: sharedUserId="") cannot be used directly, and can only be called through Java reflection.
There are also dynamic proxy modes in Android and Android plug-in (hook) that use reflection. I will not explain them one by one here, because each technical point needs to be digged deep to understand thoroughly.
2.3 Pros and cons of reflection
advantage:
1. Private methods and variables can be called
2. You can call the hidden API interface
3. Can dynamically obtain class instances at runtime to improve code flexibility
shortcoming:
1. Security issue: Reflection can obtain all methods and properties corresponding to the class. If there is an external call, calls that exceed expectations may occur, resulting in security risks, and also destroy the encapsulation feature of object-oriented programming in Java.
2. Performance issues: Whether you are getting Class, Method or Field through strings, you need to dynamically parse and match the dynamic linking mechanism of the JVM, which will inevitably cause performance overhead. Each reflection call will cause additional security verification by the Java security mechanism, resulting in performance overhead. Reflective code makes it impossible for many JVM runtime optimizations.
3. Java reflection mechanism API
The Java reflection mechanism API is mainly classes and packages.
kind | illustrate |
Represents the entire bytecode. Represents a type and represents the entire class. | |
Represents the construction method of bytecode in bytecode. Represents the constructor in the class. | |
Represents the method bytecode in bytecode. Represents the method in the class. | |
Represents the attribute bytecode in the bytecode. Represents member variables in the class (static variable + instance variable) |
3.1 Get Class object
Way | illustrate |
Object.getClass(); | |
Class name.class | |
("full path to class"); | Recommend this writing method |
package ; public class ClassObject { public static void main(String[] args) throws ClassNotFoundException { //The first type: object.getClass(); People people = new People(); Class clazz1 = (); (clazz1); //The second type: class name.class Class clazz2 = ; (clazz2); //The third type: (package name. class name) Class clazz3 = (""); (clazz3); } }
The first type: directly new the object, and then get the class object through the object. But if you think about it, you can directly new the class objects. In the outside world, except that private variables and methods cannot be accessed directly, they can be called directly. Why do I reflect it? Writing so much code is not a difficult situation for yourself. I don’t recommend it!
The second type: obtain the bytecode class object through the class name.class. You need to import the package, and the dependency is relatively strong, otherwise the compiler will report an error.
The third type: Class's static method is highly secure, and the parameters are: class package name + class name
The operation results are as follows:
class
class
class
All three are the same Class object. During runtime, only one Class object is generated.
3.2 Reflection call class constructor
Method name explanation
Method name | Explanation |
public Constructor[] getConstructors() |
All "public" constructors |
public Constructor getConstructor(Class... parameterTypes) | Get the common constructor method for specifying parameters |
public Constructor[] getDeclaredConstructors() | Get all constructors (including private, protected, default, public) |
public Constructor getDeclaredConstructor(Class... parameterTypes) | : Get the "Constructor for the specified parameter" can be private, or protected, default, and public; |
newInstance(Object... initargs) | Use thisConstructor The constructor represented by the object creates a new instance of the declaration class of the constructor and initializes the instance with the specified initialization parameter. Its return value is T type, so newInstance is a new instance object of the famous class that creates a constructor method, which is equivalent to People p = new People(); |
Let's take a look at the Demo
package ; public class People { private String name; private int age; public String sex; private long height; public People() { ("The public parameterless constructor method has been called and the execution has been completed"); } public People(String name) { = name; ("CallpublicGlycologic construction method String:name = " + name); } private People(int age, String sex) { = age; = sex; ("Calling private has parameter constructor age:"+ age + " sex:" + sex); } People(long height) { = height; ("The default has parameter constructor height:"+ height ); } }
Reflection test class:
package ; import ; import ; public class ReflectPeople { public static void main(String[] args) { try { //Get People class object Class peopleclass = (""); ("*********************************************************); ("Reflective object:" + peopleclass); //Get all constructors ("****************************** Print all constructors****************************************); Constructor[] conArray = (); for(Constructor c : conArray){ (c); } ("*************** The first type: call the default parameterless constructor through reflection and create a people class instance object*******************************************); //Returns a Constructor object that reflects the specified public class function of the class represented by the Constructor object. Object constructorPublic = (); ("Objects with no parameter construction method:" + ()); //Use the constructor represented by this Constructor object to create and initialize a new instance of the declared class of the constructor using the specified initialization parameters. //The newInstance() method actually calls the parameterless constructor method, and it is necessary to ensure that the parameterless construct exists to Object peopleobject1 = ((Constructor) constructorPublic).newInstance(); ("Create a new instance of people1 object: " + (People)peopleobject1); ("*************** The second type: call the public parameter constructor through reflection and create the People class instance object*******************************************"); Object peopleobject2 = ().newInstance("Party A"); ("Create a new instance of people2 object: " + (People)peopleobject2); ("*************** The third type: call private parameter constructor through reflection and create People class instance object**********************************************"); //Note that if you access the constructor related to protect private, you need to use getDeclaredConstructor to API //Returns a Constructor object that reflects the specified class function of the class or interface represented by the Constructor object. Constructor constructorPrivate = (, ); //Accessing the private constructor method, you must write this sentence, otherwise you will get an error (true); ("Object with parameter private constructor:" + (, )); Object peopleobject3 = (20, "men"); ("Create a new instance of people3 object: " + peopleobject3); ("************ The fourth type: call the default parameter constructor through reflection and create the People class instance object*******************************************); Constructor constructorDefault = (); //Access the public protect default constructor method, you don't need to write this sentence //(true); ("Object with parameter default constructor:" + ()); Object peopleobject4 = (185); ("Create a new instance of people4 object: " + peopleobject4); } catch (ClassNotFoundException | NoSuchMethodException e) { (); } catch (IllegalAccessException e) { (); } catch (InstantiationException e) { (); } catch (InvocationTargetException e) { (); } } }
Print log:
************************************************
Reflective object: class
*************************** Print all constructors*******************************
(long)
private (int,)
public ()
public ()
**************** The first type: call the default parameterless constructor through reflection and create a people class instance object ****************************************
Objects with parameterless construction method: public ()
The public parameterless constructor method has been called and the execution has been completed
Create a new instance of people1 object: @2a139a55
**************** The second type: call the public parameter constructor through reflection and create the People class instance object****************************************
Call public parameter constructor String: name = Party A
Create a new instance of people2 object: @15db9742
**************** The third type: call private parameter constructor through reflection and create People class instance object****************************************
Object with private constructor parameters: private (int,)
Calling private has parameter constructor age: 20 sex:men
Create a new instance of people3 object: @6d06d69c
*************The fourth type: call the default parameter constructor through reflection and create the People class instance object****************************************
Object with parameter default constructor: (long)
Call default with parameter constructor height: 185
Create a new instance of people4 object: @7852e922
Through the above example, summarize:
1. Reflect Class objects, reflective Constructor objects, and reflective class instance objects are 3 different objects. If you are not familiar with the API at the beginning, it is recommended to create them separately;
The difference between () and getDeclaredConstructor (class <?>... parameterTypes) methods The former is to obtain the Constructor object of the public type constructor method, and the latter is to obtain the Constructor object of the full type (public protect default private) type constructor method
3. When reflecting private constructors, you must setAccessible(true), otherwise an error will be reported. * true means: security checks are prohibited when using Java language, brute-force access.
4. When calling the newInstance() method in the Constructor class, note that newInstance does not have parameters (it can be written without parameters, or it can be written as null). This method actually calls the parameterless constructor method inside. It is necessary to ensure that the parameterless construct exists, otherwise an exception will be thrown.
3.3 Reflection calling methods in class
Method name | illustrate |
public Method[] getMethods() | Get all "public methods"; (The methods containing the parent class also contain the Object class) |
public Method getMethod(String name,Class<?>... parameterTypes) | Gets the public member method class object of the specified parameter. |
public Method[] getDeclaredMethods() | Get all member methods, including private (excluding inherited) |
public Method getDeclaredMethod(String name,Class<?>... parameterTypes) | Get the method object for the specified parameter |
public Object invoke(Object obj,Object... args) | Call this on a method object with specified parametersmethod The underlying method of object representation. |
Let's take a look at this example
package ; public class MethodTest { public MethodTest() { ("Call the default common constructor method of MethodTest"); } String fruit = "apple"; int milliliter = 0; char game = 'X'; String mood = "happy"; public void eat(String fruit) { = fruit; ("The fruit eaten by calling the public member method eat is:" + fruit); } int drink(int milliliter) { = milliliter; ("Call the default member method to drink the amount of ml of water:" + milliliter); return milliliter; } protected void play(char game) { = game; ("Call protected member method to play the game:" + game); } private String happy(String mood) { = mood; ("Calling private member method happy today's mood:" + mood); return mood; } }
Reflection test class
package ; import ; import ; public class ReflectMethod { public static void main(String[] args) { try { ("*********************************************************); //Get the class object of the method class Class methodClass = (""); ("Reflective object:" + methodClass); ("******************************************************************); //Return a "Method Array Object": reflects all declared methods in the class or interface, including public, protected, default (package) access and private methods, but does not include inherited methods. Method[] methods = (); for (Method m : methods) { (m); } ("*************** The first ********** Call the public member method in the reflection class *************************************); //Returns a method object that represents the specified declared method object of the class or interface represented by this representation. //The first parameter is the method name, the second variable parameter: the parameter passed in this method Method methodPublic = ("eat", ); //PUBLIC :1 PRIVATE:2 PROTECTED:4 PACKAGE(default):8 ("Print the modifier for this public method:" + ()); ("Print the public method object to represent the name of the method: "+()); ("Print the number of formal parameters of the public method object executable:" + ()); //Instantiate a MethodTest class object. Each class has a default parameterless constructor, which can be written or not written //But if there is a constructor with parameters in the class, then the constructor without parameters must be written, otherwise an error will be reported when new objects are reported. MethodTest objMethodTest = (MethodTest)().newInstance(); ("MethodTest class object:" + objMethodTest); //invoke method First parameter: object called from the underlying method If the underlying method is static, the first parameter obj object passes null. //Second parameter: Parameters of this method call //If the method completes normally, the returned value will be returned to the caller. Object objectreturn1 = (objMethodTest, "Pineapple"); //The return value of the eat method is null ("eat method returns:" + objectreturn1); ("*************** The second type of ********** Call the private member method in the reflection class *************************************"); Method methodPrivate = ("happy", ); ("Print the modifier for this private method:" + ()); ("Print the private method object to represent the name of the method: "+()); ("Print the number of formal parameters of the public method object executable:" + ()); //If you are accessing a private method, you should add this sentence to prohibit security checks when using Java language (true); Object objectreturn2 = (objMethodTest, "Super nice"); ("happy method returns:"+objectreturn2); ("*************** The third type of ************* Calling the protected member method in the reflection class ****************************************"); Method methodProtected = ("play", ); ("Print the modifier for the protected method:" + ()); ("Print the protected method object to represent the name of the method: "+()); ("Print the number of formal parameters of the protected method object executable:" + ()); Object objectreturn3 = (objMethodTest, 'Y'); ("play method returns:"+objectreturn3); ("*************** The fourth type of ************* Call the default member method in the reflection class *************************************"); Method methodDefault = ("drink", ); ("Print the modifier for the protected method:" + ()); ("Print the protected method object to represent the name of the method: "+()); ("Print the number of formal parameters of the protected method object executable:" + ()); Object objectreturn4 = (objMethodTest, 180); ("drink method returns:"+objectreturn4); } catch (ClassNotFoundException | NoSuchMethodException e) { (); } catch (IllegalAccessException e) { (); } catch (InstantiationException e) { (); } catch (InvocationTargetException e) { (); } } }
Print log:
************************************************
Reflective class object:class
************************************ Get all member methods in the reflection class****************************
public void ()
private ()
protected void (char)
int (int)
*************** The first type of ************* Calling the public member method in the reflection class *******************************
Print the modifier for this public method: 1
Print this public method object. The name of the method is: eat
Print the public method object The number of formal parameters of the executable file: 1
Call MethodTest's default common constructor
MethodTest class object:@15db9742
Call the public member method eat the fruit you eat is: pineapple
The return value of the eat method is: null
*************** The second type of ********** Calling the private member method in the reflection class **********************************
Print the modifier for this private method: 2
Print this private method object. The name of the method is expressed: happy
Print the public method object The number of formal parameters of the executable file: 1
Call private member method happy Today's mood: super nice
Happy method return value is: super nice
**************** The third type ********** Call the protected member method in the reflection class *************************************
Print modifiers for the protected method: 4
Print the protected method object. The name of the method is represented: play
Print the protected method object The number of formal parameters of the executable file: 1
Call protected member method to play the game:Y
The return value of the play method is: null
*************** The fourth type of ************* Call the default member method in the reflection class **********************************
Print the modifier for the protected method: 0
Print the protected method object. The name of the method is: drink
Print the protected method object The number of formal parameters of the executable file: 1
Call default member method drink ml of water: 180
The return value of the drink method is: 180
The code is basically commented, and the example above is summarized:
1. Reflect class object, reflect method object Reflection class instance object is 3 different objects, and it should be distinguished.
2. When calling private method in reflection, you must prohibit security checks when using Java language. SetAccessible(true) is required. Other modifier methods do not need to add this sentence.
3. (Reflection Method object).invoke(Object obj, Object ...args) Understanding of method parameters:
1. The first parameter is a reflection class instance object constructed by the reflection method
2. The second variable parameter is: The parameters that are passed in this method
3. If the method completes normally, the return value will be returned.
3.4 Member variables in reflective class
method | illustrate |
Field[] getFields() | Get all "public fields" |
public Field getField(String fieldName) | Get the common fields for the specified parameter |
.Field[] getDeclaredFields() | Get all fields, including: private, protected, default, public; |
public Field getDeclaredField(String fieldName) | Get a field (including private ones) |
set(Object obj, Object value) | Will specifyField Object Set to the specified new value |
We explain through Demo:
package ; /** * desc: FieldTest class for reflection calls * version: 1.0 */ public class FieldTest { public FieldTest() { ("Calling the default parameterless constructor of FieldTest"); } public int age = 18; private String name = "Zhang San"; String sex = "male"; protected String phoneNum = "123456789"; public int getAge() { return age; } public String getName() { return name; } public String getSex() { return sex; } public String getPhoneNum() { return phoneNum; } public void setAge(int age) { = age; } public void setName(String name) { = name; } public void setSex(String sex) { = sex; } public void setPhoneNum(String phoneNum) { = phoneNum; } @Override public String toString() { return "FieldTest{" + "age=" + age + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", phoneNum='" + phoneNum + '\'' + '}'; }
Reflection test class:
package ; import ; import ; import ; /** * desc: Implementation class that reflects fields (Field) in FiledTest class * version: 1.0 */ public class ReflectField { public static void main(String[] args) { //Use normal new object method to assign values to fields, print object values, and test /* FieldTest objcetFieldTest = new FieldTest(); (15); ("xiaomao"); ("12345678"); ("male"); (());*/ //Modify the field value through reflection try { //Get Class object through reflection Class FieldTestClass = (""); //Use reflection to modify the value of the field (member variable) ("************Get all fields(Including common、private、Protected、Default)********************"); Field[] fields = (); for (Field f : fields) { (f); } //Construct FieldTestl class object using reflection FieldTest objFieldTest = (FieldTest) ().newInstance(); ("********************* Reflection gets the public field and calls **********************************************); //Returns a Field object that represents a specified declared field object of the class or interface. Field fieldPublic = ("age"); ("Modifier for this field:" + ()); ("The name of the field:" + ()); /* * Get the value of the field: getInt(Object obj) getLong(Object obj) get(Object obj) get(Object obj) and other methods * * obj: A class object constructed through reflection method * */ //Get the default value of the int type instance field ("Get the default value of age by reflection: " + (objFieldTest)); /* Set the value of the field: Field public void set(Object obj,Object value): Parameter description: : Class object constructed through reflection method : The value to be set for the field; */ (objFieldTest, 20); //Call getAge() method through reflection Method method = ("getAge"); Object objectReturn = (objFieldTest); ("After setting the new value through reflection, the value of age:" + objectReturn); ("****************** Reflection gets the private field and calls **********************************************"); //In the actual project, because private variables and methods cannot be called in external classes, reflection comes in handy at this point Field fieldPrivate = ("name"); //Private field must be called setAccessible(true) security check when using Java language is prohibited (true); ("Get the default value of age by reflection: " + (objFieldTest)); //Modify the value of the private variable name (objFieldTest, "Li Si"); //Call getName() method through reflection Method objectMethod = ("getName"); Object objectReturn1 = (objFieldTest); ("After setting the new value through reflection, the value of name:" + objectReturn1); } catch (ClassNotFoundException | NoSuchMethodException e) { (); } catch (InstantiationException e) { (); } catch (InvocationTargetException e) { (); } catch (IllegalAccessException e) { (); } catch (NoSuchFieldException e) { (); } }
Print log:
**************** Get all fields (including shared, private, protected, default)******************************
public int
private
protected
Call FieldTest default parameterless constructor
****************Reflection gets the public field and call *******************************************
Modifier for this field: 1
The name of this field: age
Get the default value of age by reflection: 18
After setting the new value through reflection, the value of age: 20
****************Reflection gets the private field and calls ****************************************
Get the default value of age by reflection: Zhang San
After setting the new value through reflection, the value of name: Li Si
Through examples, the summary is as follows:
1. Reflect class object, reflect field object Reflection class instance object is 3 different objects, and it should be distinguished.
2. When the private field is called in reflection, it is necessary to prohibit security checks when using Java language, and setAccessible(true)
3. Field public void set(Object obj,Object value):
Parameter description:
: Class object constructed through reflection method
: The value to be set for the field;
3.5 Static methods and variables in reflection class
How to modify the variables modified by static? Static variables and methods are initialized before the class is instantiated (the class initialization stage). Static variables and methods belong to the class itself and have nothing to do with the specific objects derived from new, so when we obtain variables, we do not need to pass them into the object, but directly pass them into null.
The demo is as follows:
package ; public class StaticFieldTest { public StaticFieldTest() { ("Call StaticFieldTest parameterless constructor"); } // Static variable public static int age = 15; public static void setAge(int age) { = age; } // Static method public static int getAge() { return age; } }
Reflection test class:
package ; import ; import ; import ; public class ReflectStatic { public static void main(String[] args) { try { //Get StaticFieldTest class object Class staticClazz = (""); //Get static Field object Field staticField = ("age"); //Because it is a pulic modifier, you don't need to write this sentence (true); //Use the set method to modify the value. The static variable is a subordinate class. You can directly pass null without passing it into the class instance object. (null, 25); //Verify the modified value Method agetet = ("getAge"); // Static method is a subordinate class, you can directly pass null without passing in class instance objects int agetest = (int) (null); ("****************************** Print the modified age value*********************************); (agetest); } catch (ClassNotFoundException | NoSuchMethodException e) { (); } catch (IllegalAccessException e) { (); } catch (InvocationTargetException e) { (); } catch (NoSuchFieldException e) { (); } }
Print result:
*************************** Print the modified age value******************************
25
The summary is as follows:
1. For static variables and methods, because they belong to the class itself, they are initialized before the class is instantiated. When passing in the obj object parameters, just pass in null directly.
4. Application of reflection in Android
4.1 Reflection implementation to get the name of the top-level activity
As described in the background of the foreword, with the above theoretical knowledge as the basis, the implementation code is as follows:
/** * @description: Get the top-level activity name through reflection * @param: null * @return: boolean Returns true if it is the target activity */ public boolean isTopTargetActivity() { try { //Get class object through package name and class name reflection Class activityThreadClass = (""); //The second type: reflection creates an activiyThread object. Reflection calls a static method, and the first parameter obj object passes null Object activityThreadObj = ("currentActivityThread").invoke(null); ("test", "====activityThreadObj: "+activityThreadObj); //Get mActivities Field object final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>(); Field activitiesField = ("mActivities"); //Check when using Java language access is prohibited (true); //Return the value of the field represented by the field Field Map activities = (Map) (activityThreadObj); for (Object activityClientRecord : ()) { //Get ActivityClientRecord class object Class activityRecordClass = (); //Get boolean paused field object Field pausedField = ("paused"); //Allow brute-force access and prohibit java language running security checks (true); //The judgment conditions of Activity onResume if (!(activityClientRecord)) { //Get Activity activity field object Field activityField = ("activity"); (true); //Get the object of the currently displayed activity Activity activity = (Activity) (activityClientRecord); //Get the name of the current activity String className = ().toString(); ("test", "====Obtained by reflectionclassName===="+className); if ("".equals(className)) { return true; } } } } catch (ClassNotFoundException e) { ("test", "======ClassNotFoundException===="+()); } catch (InvocationTargetException e) { ("test", "======InvocationTargetException===="+()); } catch (NoSuchMethodException e) { ("test", "======NoSuchMethodException===="+()); } catch (NoSuchFieldException e) { ("test", "======NoSuchFieldException===="+()); } catch (IllegalAccessException e) { ("test", "======IllegalAccessException===="+()); } return false; }
4.2 Reflection call set get method in SystemProperties
Furthermore, for example, third-party applications cannot directly call the get set method in SystemProperties, and we can also implement it through reflection. This tool class has been implemented well and can be used directly:
public class SystemPropertiesUtils { private static final String TAG = "SystemPropertiesUtils"; private static Class<?> mClassType = null; private static Method mGetMethod = null; private static Method mGetIntMethod = null; private static Method mGetBooleanMethod = null; private static Class<?> getSystemPropertiesClass() throws ClassNotFoundException { if (mClassType == null) { mClassType = (""); } return mClassType; } private static Method getMethod() throws Exception { if (mGetMethod == null) { Class clazz = getSystemPropertiesClass(); mGetMethod = ("get", ); } return mGetMethod; } private static Method getIntMethod() throws Exception { if (mGetIntMethod == null) { Class clazz = getSystemPropertiesClass(); mGetIntMethod = ("getInt", , ); } return mGetIntMethod; } private static Method getBooleanMethod() throws Exception { if (mGetBooleanMethod == null) { Class clazz = getSystemPropertiesClass(); mGetBooleanMethod = ("getBoolean", , ); } return mGetBooleanMethod; } public static String get(String key, String def) { try { String value = (String) getMethod().invoke(null, key); if (!(value)) { return value; } } catch (Exception e) { (TAG, "Unable to read system properties"); } return def; } public static int getInt(String key, int def) { int value = def; try { value = (int) getIntMethod().invoke(null, key, def); } catch (Exception e) { (TAG, "Unable to read system properties"); } return value; } public static boolean getBoolean(String key, boolean def) { boolean value = def; try { value = (Boolean) getBooleanMethod().invoke(null, key, def); } catch (Exception e) { (TAG, "Unable to read system properties"); } return value; } }
4.3 Create Bitmap thumbnails through reflection
public static Bitmap createVideoThumbnail(String filePath) { // MediaMetadataRetriever is available on API Level 8 // but is hidden until API Level 10 Class<?> clazz = null; Object instance = null; try { clazz = (""); instance = (); Method method = ("setDataSource", ); (instance, filePath); // The method name changes between API Level 9 and 10. if (.SDK_INT <= 9) { return (Bitmap) ("captureFrame").invoke(instance); } else { byte[] data = (byte[]) ("getEmbeddedPicture").invoke(instance); if (data != null) { Bitmap bitmap = (data, 0, ); if (bitmap != null) return bitmap; } return (Bitmap) ("getFrameAtTime").invoke(instance); } } catch (IllegalArgumentException ex) { // Assume this is a corrupt video file } catch (RuntimeException ex) { // Assume this is a corrupt video file. } catch (InstantiationException e) { (TAG, "createVideoThumbnail", e); } catch (InvocationTargetException e) { (TAG, "createVideoThumbnail", e); } catch (ClassNotFoundException e) { (TAG, "createVideoThumbnail", e); } catch (NoSuchMethodException e) { (TAG, "createVideoThumbnail", e); } catch (IllegalAccessException e) { (TAG, "createVideoThumbnail", e); } finally { try { if (instance != null) { ("release").invoke(instance); } } catch (Exception ignored) { } } return null; }
There is a public parameterless construction method in the class. You can get this class object through reflection().newInstance()
Next, get the Method Field object and then modify the value of the method variable through the invoke set method.
5. Summary
Reflection is developed and applied in Android, including Class objects, Constructor objects, Method objects. Field objects should be understood and used proficiently. Combined with source code, read more and write more. I believe you can also carry reflection.
This is the end of this article about the detailed explanation of the reflection mechanism in Android development. For more related content on Android reflection mechanism, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!