您的位置:首页 > 移动开发 > Android开发

[Android]反射的使用及如何防止反射

2016-06-01 18:29 861 查看

反射的使用

1.使用反射机制获取安卓内部资源

(1) 获取系统Toast的内部资源(layout/view)

Toast的布局文件:com.android.internal.R.layout.transient_notification
Toast的文本视图:com.android.internal.R.id.message

Toast的相关源码:
LayoutInflater inflate = (LayoutInflater)

                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);

TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);

在安卓的应用程序中无法直接使用这些系统的内部资源,但可以通过反射机制获取并使用,代码如下:
            try{

                Class<?> clazz = Class.forName("com.android.internal.R$layout");

                Field field = clazz.getField("transient_notification");

                field.setAccessible(true);

                int id_layout = field.getInt(null);

                clazz = Class.forName("com.android.internal.R$id");

                field = clazz.getField("message");

                field.setAccessible(true);

                int id_message = field.getInt(null);

                View mImprovedToastView = inflate.inflate(id_layout, null);

                TextView mImprovedToastTextView = (TextView)mImprovedToastView.findViewById(id_message);

            } catch (Exception e){

            }

(2) 获取系统状态栏的高度

        try {

            Class<?> c = Class.forName("com.android.internal.R$dimen");

            Object obj = c.newInstance();

            Field field = c.getField("status_bar_height");

            int x = Integer.parseInt(field.get(obj).toString());

            int sbar = mContext.getResources().getDimensionPixelSize(x);

        } catch (Exception e) {

            e.printStackTrace();

        }

(3) 获取系统字符串

            try {

                Class sysResCls = Class.forName("com.android.internal.R$string");

                Field webUserAgentField = sysResCls.getDeclaredField("web_user_agent");  // 也可以写成 Field field = sysResCls.getField("web_user_agent");

                Integer resId = (Integer) webUserAgentField.get(null);   // 也可以写成  resId = webUserAgentField.getInt(null);

                String webUserAgent = context.getString(resId);

            } catch (Throwable ignored) {

            }

2.使用反射机制调用安卓系统内部类的方法

(1) 获取设备的串号:

        String sn = null;

        try {

            Class<?> c = Class.forName("android.os.SystemProperties");

            Method get = c.getMethod("get", String.class, String.class );

            sn = (String)(get.invoke(c, "ro.serialno", "unknown" ));

            if(sn== null || "".equals(sn)){

                // fail to get the serial number

            }else {

                // succeed to get the serial number

            }

        }

        catch (Exception ignored) {

        }

(2) 判断某个类是否存在的方法:

                    boolean  isClassExisted = false;
                    try {

                        Class.forName("com.xxx.xxx.util.ClassName");

                        isClassExisted = true;

                    } catch (ClassNotFoundException ignored) {

                        //Ignored.
                    }

(3) 获取MTK手机的TeleInfo信息:

        TeleInfo teleInfo = new TeleInfo();

        try {

            Class<?> phone = Class.forName("com.android.internal.telephony.Phone");

            Field fields1 = phone.getField("GEMINI_SIM_1");

            fields1.setAccessible(true);

            int simId_1 = (Integer) fields1.get(null);

            Field fields2 = phone.getField("GEMINI_SIM_2");

            fields2.setAccessible(true);

            int simId_2 = (Integer) fields2.get(null);

            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

            Method getSubscriberIdGemini = TelephonyManager.class.getDeclaredMethod("getSubscriberIdGemini", int.class);

            String imsi_1 = (String) getSubscriberIdGemini.invoke(tm, simId_1);

            String imsi_2 = (String) getSubscriberIdGemini.invoke(tm, simId_2);

            teleInfo.imsi_1 = imsi_1;

            teleInfo.imsi_2 = imsi_2;

            Method getDeviceIdGemini = TelephonyManager.class.getDeclaredMethod("getDeviceIdGemini", int.class);

            String imei_1 = (String) getDeviceIdGemini.invoke(tm, simId_1);

            String imei_2 = (String) getDeviceIdGemini.invoke(tm, simId_2);

            teleInfo.imei_1 = imei_1;

            teleInfo.imei_2 = imei_2;

            Method getPhoneTypeGemini = TelephonyManager.class.getDeclaredMethod("getPhoneTypeGemini", int.class);

            int phoneType_1 = (Integer) getPhoneTypeGemini.invoke(tm, simId_1);

            int phoneType_2 = (Integer) getPhoneTypeGemini.invoke(tm, simId_2);

            teleInfo.phoneType_1 = phoneType_1;

            teleInfo.phoneType_2 = phoneType_2;

        } catch (Exception e) {

            e.printStackTrace();

        }

如何防止反射

<待续>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息