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

原创 2016年06月01日 18:29:54

反射的使用


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();
        }


如何防止反射


<待续>

重写BaseAdapter的样例

(1)用于ListView,用来设置每项的背景  1 package com.studio.basf.libs;  2  3 import java.util.List;  4  5...

Glide 图片请求库(工具类)

Glide :Google推荐的图片加载库,专注于流畅的滚动,Github下载地址: https://github.com/bumptech/glide/releases/ 封装的工具类: ...

Android之反射的使用

知识点: 1、反射的概念; 2、反射API介绍; 3、反射在Android的使用实例; Android开发中,我们也许用到的反射并不常见,或者说几乎没有用到,因为我们都是被一般的面向对象思...

Android 中反射的使用

主要写了反射在Android(java)中的使用。 反射对象的三种方式,反射方法和字段,程序里常用的回调在反射里改怎么写。...
  • zzyawei
  • zzyawei
  • 2017年04月20日 18:21
  • 136

反射的使用

  • 2016年08月04日 17:39
  • 3KB
  • 下载

java 反射的使用

  • 2015年11月09日 12:01
  • 3KB
  • 下载

android关于jni反射的一些操作

android关于jni反射的一些操作 本文说明一下当用到jni的时候需要的反射功能及一些操作,应用场景在于c++反射调用java的一些变量及类的操作,下面截取项目中的代码片段。具体的可以看注释 ...

java反射的使用

  • 2017年05月24日 17:04
  • 5KB
  • 下载

反射的简单使用源码

  • 2007年11月22日 14:35
  • 5KB
  • 下载

Android listview 利用反射的自动绑定Adapter

网上有很多介绍ListView的用法,大多涉及了Adapter。Android提供的Adapter主要有ArrayAdapter, SimpleAdapter, SimpleCursorAdapter...
  • doon
  • doon
  • 2014年01月07日 16:19
  • 3166
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[Android]反射的使用及如何防止反射
举报原因:
原因补充:

(最多只允许输入30个字)