精华内容
下载资源
问答
  • Android 反射获取私有方法,成员变量

    千次阅读 2017-09-27 10:12:48
    //获取变量名为lottieDrawable 的变量 field.setAccessible(true);//开放权限 LottieDrawable drawable = (LottieDrawable) field.get(obj);//从对象中获取该成员变量值 //field.getInt(obj),field.getBoolean...
    public class AppInfo {
    
        private String mAppName;
    	public String getAppName() {
            return mAppName;
        }
    
        public void setAppName(String appName) {
            this.mAppName = appName;
        }
    }
    

    获取方法

     public static void test() {
            try {
                获取class 实例
                Class<?> clz = Class.forName("com.xxx.xxx.bean.AppInfo");
                //获取object实例,即AppInfo实例,这里会调用无参构造方法
                Object obj = clz.newInstance();
                //调用方法setAppName,传入String 类型的参数
                Method mothod1 = clz.getMethod("setAppName",String.class);
                //执行该方法,实参为"hhhhh",obj为要操作的对象
                mothod1.invoke(obj,"hhhhh");
                //调用getAppName 方法,不需要传参
                Method mothod = clz.getMethod("getAppName");
                //在obj对象中,执行该方法
                String name = (String) mothod.invoke(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    获取成员变量

     			public void getField(Object obj) {
     				Class<?> class1 =  obj.getClass();
                	Field[] fields = class1.getDeclaredFields();//获取全部成员变量
                	Field[] fields = class1.getDeclaredFields();
                    for( Field field : fields ){
                    	Log.i("test", "name==" + field.getName());//依次获取成员变量名
               	 	}
                	Field field = class1.getDeclaredField("lottieDrawable");//获取变量名为lottieDrawable 的变量
                	field.setAccessible(true);//开放权限
                	LottieDrawable drawable = (LottieDrawable) field.get(obj);//从对象中获取该成员变量值
                	//field.getInt(obj),field.getBoolean(obj)....
                }
    
    展开全文
  • 使用场景: 因为系统控件已经封装好了,而我们又需要自定义一些内容。 例如: ...等一些需要更改私有变量的控件   实现代码片段 Class&lt;?&gt; class1 = Class.forName("android...

    使用场景:

    因为系统控件已经封装好了,而我们又需要自定义一些内容。


    例如:
    1、toolbar左边的setNavigationIcon我们需要自定义,做一动画效果,
    2、recyclerView的滑动监听OnItemTouchListeners。
    等一些需要更改私有变量的控件
     

    实现代码片段

    Class<?> class1 = Class.forName("android.support.v7.widget.Toolbar");
    Field field = class1.getDeclaredField("mNavButtonView");//变量名称 mNavButtonView:是toolbar中的一个私有变量
    field.setAccessible(true);//开放权限
    mNavButtonView = (ImageButton) field.get(treeToolbar);//treeToolbar类实例

    toolbar例子:获取左边的ImageView,设置为自己的帧动画

    /**
         * 运行升级动画
         */
        public void runUpgradeAnim() {
            try {
                Class<?> class1 = Class.forName("android.support.v7.widget.Toolbar");//有时必须是路径形式,不能是.getClass()获得和class,可能原因获取是IDE缓存问题。
                Field field = class1.getDeclaredField("mNavButtonView");//变量名称
                field.setAccessible(true);//开放权限
                mNavButtonView = (ImageButton) field.get(treeToolbar);
                //下面是自己的自定义操作
                mNavButtonView.setImageResource(R.drawable.anim_upgrade);
                AnimationDrawable animationDrawable2 = (AnimationDrawable) mNavButtonView.getDrawable();
                if (!animationDrawable2.isRunning()) {
                    animationDrawable2.start();
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

    recyclerView例子:获取私有变量mOnItemTouchListeners,将之清除,重新设置新的

    public void clearSwipe(Object object) {
            try {
                Class<?> recyclerViewClass = Class.forName("android.support.v7.widget.RecyclerView");
                Field field = recyclerViewClass.getDeclaredField("mOnItemTouchListeners");
                field.setAccessible(true);
                ArrayList<RecyclerView.OnItemTouchListener> mOnItemTouchListeners = (ArrayList<RecyclerView.OnItemTouchListener>) field.get(object);
                mOnItemTouchListeners.clear();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

    如此就可以封装成方法如下: 

        public static <T> T reflect(String clsPath, Objects instance, String reflectName) {
            try {
                return (T) reflect(Class.forName(cls), instance, reflectName);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                return null;
            }
        }
    
        public static <T> T reflect(Class<?> cls, Objects instance, String reflectName) {
            try {
                Field field = cls.getDeclaredField(reflectName);
                field.setAccessible(true);
                return (T) field.get(instance);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
                return null;
            }
        }
    }

     

    展开全文
  • public class Student {// 变量和setAge、getAge方法都是私有的 private String id, name, sex; private int age; private final static String CLASSNAME = "Student";private void setAge(int age) { t

    package com.example;

    public class Student {

    // 变量和setAge、getAge方法都是私有的
    private String id, name, sex;
    private int age;
    private final static String CLASSNAME = "Student";
    
    private void setAge(int age) {
    
        this.age = age;
    }
    
    private void getAge() {
        System.out.println("age---" + age);
    }
    
    // test方法是公有
    public void test(int i, int j) {
        System.out.println("result---" + (i + j));
    
    }
    

    }

    package com.example;

    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;

    public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            Class class1 = Class.forName("com.example.Student");
            // 或者Class class1 = Student.class;
            // 获取所有的变量,包括私有
            Field[] fields = class1.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
    
                // System.out.println(fields[i].getType());
    
                System.out.println(Modifier.toString(fields[i].getModifiers())
                        + " " + fields[i].getType().getSimpleName() + " "
                        + fields[i].getName());
            }
            // 获取所有的方法,包括私有
            Method[] methods = class1.getDeclaredMethods();
            StringBuilder parameterTypeBuilder;
            for (int i = 0; i < methods.length; i++) {
                parameterTypeBuilder = new StringBuilder(" ");// 为了美观,参数开始、结束加个空格
                Class[] classes = methods[i].getParameterTypes();
    
                for (int j = 0; j < classes.length; j++) {// 方法参数类型
                    if (classes.length > 1) {
                        parameterTypeBuilder.append(classes[j].getSimpleName()
                                + " ");
                    } else {
                        parameterTypeBuilder.append(classes[j].getSimpleName()
                                + " ");
                    }
                }
                boolean result = isEmpty(parameterTypeBuilder.toString());
                System.out.println(Modifier.toString(methods[i].getModifiers())
                        + " "
                        + methods[i].getReturnType().getSimpleName()
                        + " "
                        + methods[i].getName()
                        + ((result) ? "()" : "("
                                + parameterTypeBuilder.toString() + ")"));
                parameterTypeBuilder = null;
    
            }
    
            // 调用私有属性
    
            Student student = (Student) class1.newInstance();// 强转对象
            Field ageField = class1.getDeclaredField("age");
            ageField.setAccessible(true);
            ageField.set(student, 24);// 设置 age值
            // 调用私有方法
            Method getAgeMethod = class1.getDeclaredMethod("getAge");
            getAgeMethod.setAccessible(true);
            getAgeMethod.invoke(student);// 调用getAge
    
    
    
            //调用私有方法setAge修改值,再打印
            Method setAgeMethod = class1.getDeclaredMethod("setAge",int.class);// 调用setAge,该方法有参数
            setAgeMethod.setAccessible(true);
            setAgeMethod.invoke(student,28);// 设置age
    
            getAgeMethod.invoke(student);// 调用getAge
    
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    }
    
    private static boolean isEmpty(String text) {
        if ("".equals(text) || null == text) {
            return true;
        }
        return false;
    }
    

    }

    展开全文
  • 优点:增强代码的自适应能力(动态的创建对象)、调用一些类中的私有方法(例如通过反射机制调用android系统挂断电话的方法)。 缺点:降低程序性能。牛逼的背后总是苦逼,反射机制说白了就是通过类名去解释类,然后告诉...

    Ps:最近在研究热修复技术,其中用到了反射机制,所以复习一下,做个记录。

    什么是反射机制

    个人理解就是通过反编译获取类中所有的信息(包括:变量、方法、接口),供开发者利用。

    优缺点

    • 优点:增强代码的自适应能力(动态的创建对象)、调用一些类中的私有方法(例如通过反射机制调用android系统挂断电话的方法)。

    • 缺点:降低程序性能。牛逼的背后总是苦逼,反射机制说白了就是通过类名去解释类,然后告诉jvm我们需要做什么,肯定比jvm执行固定代码要耗时耗资源。

    常用的几个类

    api文档中反射所用到的所有类

    image

    ps:这里不讲反射机制中的代理Proxy,因为水平有限,仅仅介绍下面几个类

    1. Class:由虚拟机自动构建,表示正在运行的java程序中的类或接口(下面几个类对象基本都是通过Class类获取的)。

    2. Method:从类中获取的方法,获取方法后通过method.invoke(…)执行

    3. Field:从类中获取的成员变量

    4. Constructor:从类中获取的构造方法

    5. Array:处理通过返回获取的数组(测量长度、修改数组等等)

    6. Modifier:获取的方法或变量的修饰符(method.getModifiers()获取,如:private,public..)

    这几个类的api也很简单,基本通过方法名就能理解,不在赘述。

    一个Demo讲解用法

    Ps:本例通过反射Date类,实现获取当前时间,即:当前的毫秒数,同System.currentTimeMillis()效果一样

    //获取Date类的运行时类,Class的获取方法有3种
    //1. xxx.class() ;
    //2. xxx.forName("java.util.Date") ;  //通过全类名
    //3. XXX xxx = new XXX(); xxx.class() ;
    Class c = Date.class;
    
    //获取Date所有声明的方法包括private类型的,但不包括父类的方法
    //可以通过 c.getMethods()---获取包括父类的所有public方法,但不包括private类型方法
    Method[] ms = c.getDeclaredMethods();
    
    for (Method m : ms) {
       //获取方法需要传入的参数
       Type[] types = m.getGenericParameterTypes();
       StringBuilder builder = new StringBuilder();
       builder.append("(");
       for (Type type : types) {
            builder.append(type.toString() + ",");
       }
       int last = builder.lastIndexOf(",");
       if (last > 0) {
          builder.deleteCharAt(last);
       }
      builder.append(")");
      //获取方法的修饰类型(private、public等)
      String modifier = Modifier.toString(m.getModifiers()) ;
      //获取方法的返回类型
      String rType = m.getGenericReturnType().toString() ;
      System.out.println(modifier + " " + rType + " " + m.getName() + builder.toString());
    }
    

    image

    通过上面的代码,可以获取Date类的所有方法,上图只截取了部分,其中有个用红色方框标记的方法,是私有的,通过源码可以知道,此方法可以得到当前时间的毫秒数,我们可以通过反射机制,调用这个方法,达到获取当前毫秒数的目的

    
    Class c = Date.class;
    //通过Class实例化一个Date类对象
    Object o = c.newInstance();
    //通过上例红方框中的方法名,得到该方法的实例
    Method m = c.getDeclaredMethod("getTimeImpl");
    //设置jvm不检测此方法的访问权限(相当于暴力破除private)
    m.setAccessible(true);
    //调用getTimeImpl()方法
    long l = (long) m.invoke(o, null);
    System.out.println("currentTime:" + System.currentTimeMillis());
    System.out.println("getTimeImpl:" + l);
    

    执行结果:

    这里写图片描述

    Ps:其实这个例子并没有什么实际意义,只简单说明java反射机制的一些作用,可以调用系统不对开发者开发的功能,如果用自己写的类演示,没有丝毫意义。

    再说Array

    Array是反射机制中对数组的操作

    //我们获取TestArray类的所有成员变量,并修改data数组
    public class TestArray {
    
        private String str ;
    
        public long time ;
    
        private int[] data = new int[]{1,2,3,4,5} ;
    
        public int[] getData(){
           return data ;
        }
    
    }
    
    //获取TestArray类的所有成员变量,和获取Method基本一致,不在编写注释
    Class c = TestArray.class;
    Field[] fields = c.getDeclaredFields() ;
    for (Field field : fields) {
        String mdf = Modifier.toString(field.getModifiers()) ;
        String type = field.getGenericType().toString() ;
        String name = field.getName() ;
        System.out.println(mdf+" "+type +" "+name);
    }
    
    //修改TestArray类中的data数组
    //新建对象
    TestArray ta = new TestArray() ;
    System.out.println("修改之前的第三个数:"+person.getData()[2]);
    //获取TestArray的Class
    Class c1 = ta.getClass() ;
    //获取data成员变量
    Field m = c1.getDeclaredField("data") ;
    //抑制jvm检测访问权限
    m.setAccessible(true);
    //回去data成员变量值
    Object o = m.get(ta) ;
    //判断data是否为数组
    if(o.getClass().isArray()){
      //打印数组长度
      System.out.prinln("数组长度:"+Array.getLen(o)) ;
      //反射机制中,用Array类完成对反射数组的操作,将data数组中的第三个数改为77
       Array.set(o,2,77);
    }
    System.out.println("修改之后的第三个数:"+person.getData()[2]);
    

    结果:

    这里写图片描述

    android中2个反射机制的应用实例

    android中对反射机制应用非常广泛,比如:热修复、电话挂断。

    • 热修复:通过反射机制将生成的补丁”dex”,插入到DexPathList类的private Element[] dexElements数组的最前端,是系统查找类的时候,先找到补丁”dex”中的类,从而实现热修复的效果。ps:DexPathList是不对开发者开发的,连实例对象都获取不了,只能通过反射机制做到。

    • 电话挂断:通过android系统源码可知道,挂断电话需要调用ITelephony类的endCall()方法,系统是不对我们开放的,所有也需要通过发射机制调用endCall方法。\

    • 热修复中用到的反射机制代码,会在研究热修复的时候贴出,而反射机制挂断电话,网上有太多例子,这里就不做搬运工了。

    展开全文
  • 本文介绍 android 反射和实现原理  ...方法获取变量的值,即使方法或属性是私有的的也可以通过反射的形式调用,这种“看透class”的能力被称为内省,这种能力在框架开发中尤为重要。有些情况下,我们要使用的
  • 比如一个类的构造,属性,普通方法为私有的情况下,或者某些方法虽然不是私有的方法但是是被隐藏的方法,我们就需要使用反射才能获得他们。一般使用Class类来完成反射,这个类把成员变量划分为Filed区域,把构造划分...
  • 无法直接操作某个对象的变量和方法,比如私有方法,私有变量。 需要hook系统逻辑,比如修改某个实例的参数。 等等情况。 所以我们就需要一种机制能让我们去操作任意的类和对象。 这种机制,就是反射
  • IOC反射注解框架

    2018-10-11 21:54:23
    IOC 反射注解框架 IOC 反射框架包含了java反射、注解(运行时)、Android相关的控件注入等 Java反射 在Android中反射无处不在,当我们观看Android源码的时候,你就会...注意: 在反射私有的时候,需要设置set...
  • 关于反射(一)

    2016-11-30 15:05:59
    使用反射获取私有变量,大致分为以下几个步骤。1.获取Field在这之前,我们得先获取class对象,当然这很容易,任何类getClass()就可以了,之后我们可以通过(1).getDeclaredField(String)(获取所有field,包括私有的...
  • 反射是框架设计的灵魂,只有学好了反射,才能设计出好的...获取某些类的一些变量,调用某些类的私有方法.(举个栗子,例如在Android开发中我们可以用来开启WiFi热点,调用WifiManager中的setWifiApEnabled()方法) 增加代码
  • 发现很多Android应用的选项卡 都是显示在页面底部的,网上有资料:通过反射获取TabWidget中的私有变量,改变其值。今天反编译了腾讯微薄,发现实现这个很简单,只需将布局文件中标签加个android:layout_gravity=...
  • java 反射机制

    2010-08-01 15:26:00
    1、通过java反射机制,可以访问... 2、访问android SDK中私有方法和成员变量 3、批量出处理类成员,如R类。这里有一个很好的例子:http://www.huangzhimin.com/entries/151-error-invalid-result-data
  • Android 自动连接蓝牙

    千次阅读 2018-12-20 14:29:30
    蓝牙是手机和智能硬件通信常用的方式,蓝牙通信可分为传统蓝牙和低功耗蓝牙(BLE)。其中BLE的连接断开等操作可以通过Android SDK中...我们可以利用反射调用Android中的私有API进行连接断开操作。 0x01 声明变量 ...
  • android 选项卡(TabHost) 置底

    千次阅读 2011-12-05 07:45:39
    摘要:发现很多微薄如腾讯,新浪的选项卡都是显示在页面底部的,网上有资料:通过反射获取TabWidget中的私有变量,改变其值。今天反编译了腾讯微薄,发现实现这个很简单,只需将布局文件中标签加个android:layout_...
  • Android初级——Reflect...如果一个类当中的变量和方法为私有时,我们在其它地方就无法通过新建这个类的实例来获取它,这时候就可以采用Reflect(反射)机制来解决这个问题。通过反射我们能够获取某个类中的私有成员。
  • 发现很多Android应用的选项卡 都是显示在页面底部的,网上有资料:通过反射获取TabWidget中的私有变量,改变其值。今天反编译了腾讯微薄,发现实现这个很简单,只需将布局文件 中<TabWidget />标签加个android:...
  • 摘要:发现很多微薄如腾讯,新浪的选项卡都是显示在页面底部的,网上有资料:通过反射获取TabWidget中的私有变量,改变其值。今天反编译了腾讯微薄,发现实现这个很简单,只需将布局文件中&lt;TabWidget/&gt;...
  •  ------- android培训、java培训、期待与您交流! ----------     l枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。 l枚举元素必须位于枚举体中的最开始部分,枚举元素...
  • ---------------------- android培训、java培训、期待与您交流! ----------------------     枚举  枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让...
  • Android开发、java培训、期待与您交流! ---------------------- 枚举类: JDK1.5新特性 枚举是一个特殊的类,枚举中的元素相当于类的实例对象,其中可以定义构造方法,成员变量,普通方法和抽象方法。定义构造...
  • android培训、java培训、期待与您交流! ----------------------  一、枚举 1、  用普通类如何实现枚举功能,定义一个Weekday类,模拟枚举功能。 (1)定义一个私有构造函数。 (2)每一个类分别...
  • ------- android培训、java培训、期待与您交流! ---------- 枚举类: JDK1.5新特性  枚举是一个特殊的类,枚举中的元素相当于类的实例对象,其中可以定义构造方法,成员变量,普通方法和抽象方法。定义构造方法时...
  • ------- android培训、java培训、期待与您交流! ---------- ... 枚举就是要让某个类型的变量的取值...首先在枚举内私有他的构造方法,每个元素分别用一个公有的静态成员变量表示变量表示。然后定义若干公有方法
  • ----------------------Android培训、Java培训、java学习型技术博客、期待与您交流! ---------------------- 枚举 枚举:枚举是一种特殊的类,其中每个元素都是该类的一个实例对象。 作用:就是要让某一个...
  • for (int i = 0; i < tabWidget.getChildCount(); i++) { /** * 此方法是为了去掉系统默认的色白的底角 在 TabWidget中... * 都是私有变量,但是我们可以通过反射来获取 由于还不知道Android 2.2的接口是...
  • 反射是框架设计的灵魂,只有学好了反射,才能设计出好的框架 一.反射的概述Java反射机制是在运行状态...) 反射的作用获取某些类的一些变量,调用某些类的私有方法.(举个栗子,例如在Android开发中我们可以用来开启WiFi热点

空空如也

空空如也

1 2
收藏数 28
精华内容 11
关键字:

android反射私有变量