Android reflection: reflection realized

Transfer from Android reflection: reflection taught you realize

What is reflection?

JAVA reflection mechanism is in the operating state, for any class, are made known to all properties and methods of this class; for any object, are able to call any of its methods and properties; this information acquired dynamically and dynamic invocation function method object is called reflection mechanism java language (note keywords: running state) in other words, java programs can load class when a run that name, was informed that its full configuration (but not the methods defined), and generates its object entity, or a set value of its fields, or methods which arouse

Reflection mechanism mainly provides

  1. Determining at runtime object belongs to any class;
  2. At runtime class of an object in any configuration;
  3. Analyzing any class has member variables and methods at runtime;
  4. Call any of the object's method at run time;

java Reflection API Introduction

  1. Class Class: represents a class, located in the package java.lang
  2. Field class: the field representing the class (also known as member variables of the class attribute)
  3. Method class: class method represents
  4. Constructor class: class constructor representatives
  5. Array class: provides a dynamically created array and a static method to access the array elements

Class introduction of java

Class class is very special, it is not common constructor is called jvm (simple to understand: new object or class is loaded by the time), in Java, every class has a corresponding Class object. That is, when we write a class after compilation in the generated .class file, it will generate a Class object that represents the type of information the class.

Class three kinds of java in acquisition mode

  1. Using the object call getClass () method to get the Class object instance;
  2. Class static method the forName class () for a Class instance with the name of the class;
  3. Using .class way to get Class instance, the basic data type of package type, can also be employed to obtain Class Examples .TYPE substantially corresponding data types;

Description: During the run, if we want to produce objects of a class, Java Virtual Machine (JVM) will check whether the type of Class object has been loaded. If not loaded, JVM will find .class files based on the name of the class and load it. Once a type of Class object has been loaded into memory, you can use it to generate all objects of that type.

    //方式一
    Person person = new Person();
    Class<? extends Person> personClazz01 = person.getClass();
 
    //方式二
    try {
        Class<?> personClazz02 = Class.forName("Person");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
 
    //方式三
    Class<? extends Person> personClazz03 = Person.class;

Class java in some important ways

public Annotation [] getAnnotations () Gets this class all annotations

getClassLoader () Gets the class loader to load the class

getDeclaredMethods () Get all the methods in this class

getReturnType () method returns the type of acquisition

getParameterTypes () method for obtaining the type of incoming parameters

isAnnotation () whether it is a test of such class notes

getDeclaredConstructors () Gets all the constructors

getDeclaredMethod (String name, Class ... parameterTypes) Gets the constructor (parameter: Parameter Type .class)

getSuperclass () Get the parent of this class

getInterfaces () Gets the class implements all interfaces

getFields () Gets all modified public member variables in this class

getField (String name) Gets the name of the public member variables modified

newInstance () Returns the class represented by this Class, by calling the default (i.e., no parameters) constructor creates a new instance of

Etc. Methods

How to get the private member variables and private methods via reflection

example:
Person类

public class Person {
private String name = "zhangsan";
private String age;
 
public String getName() {
    return name;
}
 
public void setName(String name) {
    this.name = name;
}
}  
 
 
    Person person = new Person();
    //打印没有改变属性之前的name值
    System.out.println("before:" + getPrivateValue(person, "name"));
    person.setName("lisi");
    //打印修改之后的name值
    System.out.println("after:" + getPrivateValue(person, "name"));
 
 
 
/**
* 通过反射获取私有的成员变量
*
* @param person
* @return
*/
private Object getPrivateValue(Person person, String fieldName) {
 
    try {
        Field field = person.getClass().getDeclaredField(fieldName);
        // 参数值为true,打开禁用访问控制检查
        //setAccessible(true) 并不是将方法的访问权限改成了public,而是取消java的权限控制检查。
        //所以即使是public方法,其accessible 属相默认也是false
        field.setAccessible(true);
        return field.get(person);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}  

The result is:
the before: zhangsan
the After: lisi

Obtaining proprietary method of obtaining a manner similar to the way private member variables

Case presentation reflection

Person class

public class Person {
private int age;
private String name;
public Person(){
 
}
public Person(int age, String name){
    this.age = age;
    this.name = name;
}
 
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
 
}  

SuperPerson class

public class SuperPerson extends Person implements Smoke.Smoking{
private boolean isMan;
 
public void fly()
{
    System.out.println("走你~~");
}
 
public boolean isMan() {
    return isMan;
}
public void setMan(boolean iaMan) {
    isMan = iaMan;
}
@Override
public void smoke(int count) {
 
}
}  

Smoke interface class

public class Smoke {
public interface Smoking {
    public void smoke(int count);
}
}  

MainActivity:

public class MainActivity extends Activity {
 
 
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Tests();
}
 
private void Tests() {
    try {
        //通过Java反射机制得到类的包名和类名
        Test1();
        System.out.println("===============================================");
 
        //验证所有的类都是Class类的实例对象
        Test2();
        System.out.println("===============================================");
 
        //通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在],无参构造
        Test3();
        System.out.println("===============================================");
 
        //通过Java反射机制得到一个类的构造函数,并实现构造带参实例对象
        Test4();
        System.out.println("===============================================");
 
        //通过Java反射机制操作成员变量, set 和 get
        Test5();
        System.out.println("===============================================");
 
        //通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等
        Test6();
        System.out.println("===============================================");
 
        //通过Java反射机制调用类中方法
        Test7();
        System.out.println("===============================================");
 
        //通过Java反射机制获得类加载器
        Test8();
        System.out.println("===============================================");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
 
/**
* Demo1: 通过Java反射机制得到类的包名和类名
*/
public static void Test1() {
    Person person = new Person();
    System.out.println("Test1: 包名: " + person.getClass().getPackage().getName() + "," + "完整类名: " + person.getClass().getName());
}
 
/**
* Demo2: 验证所有的类都是Class类的实例对象
*/
public static void Test2() throws ClassNotFoundException {
    //定义两个类型都未知的Class , 设置初值为null, 看看如何给它们赋值成Person类
    Class<?> class1 = null;
    Class<?> class2 = null;
 
    //写法1, 可能抛出 ClassNotFoundException [多用这个写法]
    class1 = Class.forName("com.tuba.yuanyc.audiomanagerdemo.Person");
    System.out.println("Test2:(写法1) 包名: " + class1.getPackage().getName() + "," + "完整类名: " + class1.getName());
 
    //写法2
    class2 = Person.class;
    System.out.println("Test2:(写法2) 包名: " + class2.getPackage().getName() + "," + "完整类名: " + class2.getName());
}
 
/**
* Demo3: 通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在]
*/
public static void Test3() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    Class<?> class1 = null;
    class1 = Class.forName("com.android.reflect.Person");
    //由于这里不能带参数,所以你要实例化的这个类Person,一定要有无参构造函数
    Person person = (Person) class1.newInstance();
    person.setAge(26);
    person.setName("kaiven");
    System.out.println("Test3: " + person.getName() + " : " + person.getAge());
}
 
/**
* Demo4: 通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象
*/
public static void Test4() throws ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
    Class<?> class1 = null;
    Person person1 = null;
    Person person2 = null;
 
    class1 = Class.forName("com.android.reflect.Person");
    //得到一系列构造函数集合
    Constructor<?>[] constructors = class1.getConstructors();
 
    try {
        person1 = (Person) constructors[0].newInstance();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    person1.setAge(28);
    person1.setName("zhuk");
 
    person2 = (Person) constructors[1].newInstance(29, "zhuk");
 
    System.out.println("Test4: " + person1.getName() + " : " + person1.getAge() + "  ,   " + person2.getName() + " : " + person2.getAge());
 
}
 
/**
* Demo5: 通过Java反射机制操作成员变量, set 和 get
*/
public static void Test5() throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException, InstantiationException, ClassNotFoundException {
    Class<?> class1 = null;
    class1 = Class.forName("com.android.reflect.Person");
    Object obj = class1.newInstance();
 
    Field nameField = class1.getDeclaredField("name");
    nameField.setAccessible(true);
    nameField.set(obj, "cyy");
 
    System.out.println("Test5: 修改属性之后得到属性变量的值:" + nameField.get(obj));
 
}
 
 
/**
* Demo6: 通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等
*/
public static void Test6() throws ClassNotFoundException {
    Class<?> class1 = null;
    class1 = Class.forName("com.android.reflect.Person");
 
    //取得父类名称
    Class<?> superClass = class1.getSuperclass();
    System.out.println("Test6:  SuperMan类的父类名: " + superClass.getName());
 
    System.out.println("===============================================");
 
 
    Field[] fields = class1.getDeclaredFields();
    for (int i = 0; i < fields.length; i++) {
        System.out.println("类中的成员: " + fields[i]);
    }
    System.out.println("===============================================");
 
 
    //取得类方法
    Method[] methods = class1.getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {
        System.out.println("Test6,取得SuperMan类的方法:");
        System.out.println("函数名:" + methods[i].getName());
        System.out.println("函数返回类型:" + methods[i].getReturnType());
        System.out.println("函数访问修饰符:" + Modifier.toString(methods[i].getModifiers()));
        System.out.println("函数代码写法: " + methods[i]);
    }
 
    System.out.println("===============================================");
 
    Class<?> interfaces[] = class1.getInterfaces();
    for (int i = 0; i < interfaces.length; i++) {
        System.out.println("实现的接口类名: " + interfaces[i].getName());
    }
 
}
 
/**
* Demo7: 通过Java反射机制调用类方法
*/
public static void Test7() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
    Class<?> class1 = null;
    class1 = Class.forName("com.android.reflect.SuperPerson");
 
    System.out.println("Test7: \n调用无参方法fly():");
    Method method = class1.getMethod("fly");
    method.invoke(class1.newInstance());
 
    System.out.println("调用有参方法smoke(int m):");
    method = class1.getMethod("smoke", int.class);
    method.invoke(class1.newInstance(), 100);
}
 
/**
* Demo8: 通过Java反射机制得到类加载器信息
* <p/>
* 在java中有三种类类加载器。
* <p/>
* 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
* <p/>
* 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
* <p/>
* 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
*
* @throws ClassNotFoundException
*/
public static void Test8() throws ClassNotFoundException {
    Class<?> class1 = null;
    class1 = Class.forName("com.android.reflect.SuperPerson");
    String name = class1.getClassLoader().getClass().getName();
 
    System.out.println("Test8: 类加载器类名: " + name);
}
} 

operation result:

01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test1: 包名: com.tuba.yuanyc.audiomanagerdemo,完整类名: com.tuba.yuanyc.audiomanagerdemo.Person
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test2:(写法1) 包名: com.android.reflect,完整类名: com.tuba.yuanyc.audiomanagerdemo.Person
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test2:(写法2) 包名: com.android.reflect,完整类名: com.tuba.yuanyc.audiomanagerdemo.Person
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test3: zhuk : 26
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test4: yyc : 28  ,   yyc : 29
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test5: 修改属性之后得到属性变量的值:cyy
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test6:  SuperMan类的父类名: java.lang.Object
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 类中的成员: private java.lang.String com.tuba.yuanyc.audiomanagerdemo.Person.name
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 类中的成员: private int com.android.reflect.Person.age
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test6,取得SuperMan类的方法:
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数名:getAge
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数返回类型:int
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数访问修饰符:public
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数代码写法: public int com.tuba.yuanyc.audiomanagerdemo.Person.getAge()
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test6,取得SuperMan类的方法:
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数名:getName
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数返回类型:class java.lang.String
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数访问修饰符:public
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数代码写法: public java.lang.String com.tuba.yuanyc.audiomanagerdemo.Person.getName()
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test6,取得SuperMan类的方法:
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数名:setAge
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数返回类型:void
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数访问修饰符:public
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数代码写法: public void com.tuba.yuanyc.audiomanagerdemo.Person.setAge(int)
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test6,取得SuperMan类的方法:
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数名:setName
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数返回类型:void
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数访问修饰符:public
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 函数代码写法: public void com.tuba.yuanyc.audiomanagerdemo.Person.setName(java.lang.String)
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test7:
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 调用无参方法fly():
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 走你~~
01-28 17:19:29.463  14972-14972/? I/System.out﹕ 调用有参方法smoke(int m):
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================
01-28 17:19:29.463  14972-14972/? I/System.out﹕ Test8: 类加载器类名: dalvik.system.PathClassLoader
01-28 17:19:29.463  14972-14972/? I/System.out﹕ ===============================================  

Using hidden by the reflection-based system

Because SystemProperties.java class has been hidden system (with the @hide notes), so we get kind of content via Java reflection, to read through the get and set methods to set content build.prop inside.

package com.android.kaiven.tools;  
  
import android.content.Context;  
import android.util.Log;  
  
import java.io.File;  
import java.io.IOException;  
import java.lang.reflect.Method;  
  
import dalvik.system.DexFile;  
  
/** 
 * Created by zhangqing on 2017/3/1. 
 */  
public class SystemPropertiesProxy {  
    public static final String TAG = "SystemPropertiesProxy";  
  
    /** 
     * 根据给定的Key返回String类型的值 
     * 
     * @param context 上下文 
     * @param key     获取指定信息所需的key 
     * @return 返回一个String类型的值,如果不存在该key则返回空字符串 
     */  
    public static String getString(Context context, String key) {  
        String result = "";  
        try {  
            ClassLoader classLoader = context.getClassLoader();  
            @SuppressWarnings("rawtypes")  
            Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
            //参数类型  
            @SuppressWarnings("rawtypes")  
            Class[] paramTypes = new Class[1];  
            paramTypes[0] = String.class;  
            Method getString = SystemProperties.getMethod("get", paramTypes);  
            //参数  
            Object[] params = new Object[1];  
            params[0] = new String(key);  
  
            result = (String) getString.invoke(SystemProperties, params);  
        } catch (IllegalArgumentException e) {  
            //e.printStackTrace();  
            //如果key超过32个字符则抛出该异常  
            Log.w(TAG, "key超过32个字符");  
        } catch (Exception e) {  
            result = "";  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的Key返回String类型的值 
     * 
     * @param context 上下文 
     * @param key     获取指定信息所需的key 
     * @param def     key不存在时的默认值 
     * @return 返回一个String类型的值,如果key不存在, 并且如果def不为null则返回def,否则返回空字符串 
     */  
    public static String getString(Context context, String key, String def) {  
        String result = def;  
        try {  
            ClassLoader classLoader = context.getClassLoader();  
            @SuppressWarnings("rawtypes")  
            Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
            //参数类型  
            @SuppressWarnings("rawtypes")  
            Class[] paramTypes = new Class[2];  
            paramTypes[0] = String.class;  
            paramTypes[1] = String.class;  
            Method getString = SystemProperties.getMethod("get", paramTypes);  
            //参数  
            Object[] params = new Object[2];  
            params[0] = new String(key);  
            params[1] = new String(def);  
  
            result = (String) getString.invoke(SystemProperties, params);  
        } catch (IllegalArgumentException e) {  
            //e.printStackTrace();  
            //如果key超过32个字符则抛出该异常  
            Log.w(TAG, "key超过32个字符");  
        } catch (Exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key返回int类型的值 
     * 
     * @param context 上下文 
     * @param key     要查询的key 
     * @param def     默认返回值 
     * @return 返回一个int类型的值,如果没有发现则返回默认值 def 
     */  
    public static Integer getInt(Context context, String key, int def) {  
        Integer result = def;  
        try {  
            ClassLoader classLoader = context.getClassLoader();  
            @SuppressWarnings("rawtypes")  
            Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
            //参数类型  
            @SuppressWarnings("rawtypes")  
            Class[] paramTypes = new Class[2];  
            paramTypes[0] = String.class;  
            paramTypes[1] = int.class;  
            Method getInt = SystemProperties.getMethod("getInt", paramTypes);  
            //参数  
            Object[] params = new Object[2];  
            params[0] = new String(key);  
            params[1] = new Integer(def);  
            result = (Integer) getInt.invoke(SystemProperties, params);  
        } catch (IllegalArgumentException e) {  
            //e.printStackTrace();  
            //如果key超过32个字符则抛出该异常  
            Log.w(TAG, "key超过32个字符");  
        } catch (Exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key返回long类型的值 
     * 
     * @param context 上下文 
     * @param key     要查询的key 
     * @param def     默认返回值 
     * @return 返回一个long类型的值,如果没有发现则返回默认值def 
     */  
    public static Long getLong(Context context, String key, long def) {  
        Long result = def;  
        try {  
            ClassLoader classLoader = context.getClassLoader();  
            @SuppressWarnings("rawtypes")  
            Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
            //参数类型  
            @SuppressWarnings("rawtypes")  
            Class[] paramTypes = new Class[2];  
            paramTypes[0] = String.class;  
            paramTypes[1] = long.class;  
            Method getLong = SystemProperties.getMethod("getLong", paramTypes);  
            //参数  
            Object[] params = new Object[2];  
            params[0] = new String(key);  
            params[1] = new Long(def);  
            result = (Long) getLong.invoke(SystemProperties, params);  
        } catch (IllegalArgumentException e) {  
            //e.printStackTrace();  
            //如果key超过32个字符则抛出该异常  
            Log.w(TAG, "key超过32个字符");  
        } catch (Exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key返回boolean类型的值 
     * 如果值为'n','no','0','false' or 'off'返回false 
     * 如果值为'y','yes','1','true' or 'on'返回true 
     * 如果key不存在, 或者是其它的值, 则返回默认值 
     * 
     * @param context 上下文 
     * @param key     要查询的key 
     * @param def     默认返回值 
     * @return 返回一个boolean类型的值,如果没有发现则返回默认值def 
     */  
    public static Boolean getBoolean(Context context, String key, boolean def) {  
        Boolean result = def;  
        try {  
            ClassLoader classLoader = context.getClassLoader();  
            @SuppressWarnings("rawtypes")  
            Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");  
            //参数类型  
            @SuppressWarnings("rawtypes")  
            Class[] paramTypes = new Class[2];  
            paramTypes[0] = String.class;  
            paramTypes[1] = boolean.class;  
            Method getBoolean = SystemProperties.getMethod("getBoolean", paramTypes);  
            //参数  
            Object[] params = new Object[2];  
            params[0] = new String(key);  
            params[1] = new Boolean(def);  
            result = (Boolean) getBoolean.invoke(SystemProperties, params);  
        } catch (IllegalArgumentException e) {  
            //e.printStackTrace();  
            //如果key超过32个字符则抛出该异常  
            Log.w(TAG, "key超过32个字符");  
        } catch (Exception e) {  
            result = def;  
        }  
        return result;  
    }  
  
    /** 
     * 根据给定的key和值设置属性, 该方法需要特定的权限才能操作. 
     * 
     * @param context 上下文 
     * @param key     设置属性的key 
     * @param val     设置属性的value 
     */  
    public static void set(Context context, String key, String val) {  
        try {  
            @SuppressWarnings("rawtypes")  
            DexFile df = new DexFile(new File("/system/app/Settings.apk"));  
            ClassLoader classLoader = context.getClassLoader();  
            @SuppressWarnings("rawtypes")  
            Class SystemProperties = Class.forName("android.os.SystemProperties");  
            //参数类型  
            @SuppressWarnings("rawtypes")  
            Class[] paramTypes = new Class[2];  
            paramTypes[0] = String.class;  
            paramTypes[1] = String.class;  
            Method set = SystemProperties.getMethod("set", paramTypes);  
            //参数  
            Object[] params = new Object[2];  
            params[0] = new String(key);  
            params[1] = new String(val);  
            set.invoke(SystemProperties, params);  
        } catch (IllegalArgumentException e) {  
            //e.printStackTrace();  
            //如果key超过32个字符或者value超过92个字符则抛出该异常  
            Log.w(TAG, "key超过32个字符或者value超过92个字符");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
} 

Guess you like

Origin blog.csdn.net/weixin_43115440/article/details/90518787