在计算机科学领域。反射是指一类应用,它们能够自描写叙述和自控制。也就是说,这类应用通过採用某种机制来实现对自己行为的描写叙述(self-representation)和监測(examination),并能依据自身行为的状态和结果,调整或改动应用所描写叙述行为的状态和相关的语义.反射 是 Java 程序开发语言的特征之中的一个,它同意执行中的 Java 程序对自身进行检查。或者说“自审”。并能直接操作程序的内部属性。Java 的反射机制的实现要借助于4个类:class,Constructor,Field,Method;当中class代表的时类对
象,Constructor-类的构造器对象。Field-类的属性对象,Method-类的方法对象。

 1.通过反射技术能够訪问到其它包名下数据方法等。这些为一些APK换皮肤提供了方便

首先初始化skinContext

  1. try {
  2. skinContext = this.createPackageContext("com.skin",
  3. CONTEXT_IGNORE_SECURITY|CONTEXT_INCLUDE_CODE);
  4. } catch (NameNotFoundException e) {
  5. // TODO Auto-generated catch block
  6. skinContext=null;
  7. e.printStackTrace();
  8. }

能够通过以下的方法訪问到指定包名下的资源ID

  1. /**
  2. * 取得相应包的全部资源的ID
  3. * 存在MAP中
  4. * @param packageName
  5. * @return
  6. */
  7. private Map<String,Map<String, Object>> getSkinResourcesId(String packageName)
  8. {
  9. Map<String, Object> temp = null;
  10. Map<String,Map<String, Object>> resMap =new HashMap<String,Map<String,Object>>();
  11. try {
  12. //取得皮肤包中的R文件
  13. Class<?
  14. > rClass = skinContext.getClassLoader().loadClass(packageName+".R");
  15. //取得记录各种资源的ID的类
  16. Class<?>[] resClass =rClass.getClasses();
  17. String className,resourceName;
  18. int resourceId=0;
  19. for(int i=0;i<resClass.length;i++)
  20. {
  21. className = resClass[i].getName();
  22. //取得该类的资源
  23. Field field[] = resClass[i].getFields();
  24. for(int j =0;j < field.length; j++)
  25. {
  26. resourceName = field[j].getName();
  27. try {
  28. resourceId = field[j].getInt(resourceName);
  29. } catch (IllegalArgumentException e) {
  30. // TODO Auto-generated catch block
  31. e.printStackTrace();
  32. } catch (IllegalAccessException e) {
  33. // TODO Auto-generated catch block
  34. e.printStackTrace();
  35. }
  36. if(resourceName!=null && !resourceName.equals(""))
  37. {
  38. temp =new HashMap<String, Object>();
  39. temp.put(resourceName, resourceId);
  40. Log.i("DDDDD", "className:"+className+" resourceName:"+resourceName+" " +
  41. "resourceId:"+Integer.toHexString(resourceId));
  42. }
  43. }
  44. //由于内部类的关系className应该是com.skin.R$layout的形式
  45. //截掉前面的包名和.R$以方便使用
  46. className = className.substring(packageName.length()+3);
  47. resMap.put(className, temp);
  48. }
  49. } catch (ClassNotFoundException e) {
  50. // TODO Auto-generated catch block
  51. e.printStackTrace();
  52. }
  53. return resMap;
  54. }

最后通过资源ID和skinContext能够訪问到指定包下的全部资源,比如要訪问layout

  1. /**
  2. * 获取皮肤包中的layout
  3. * 并转化为VIEW
  4. * @param layoutName
  5. * @return
  6. */
  7. private View getLayoutFromSkin(String layoutName)
  8. {
  9. View view;
  10. if(resMap == null)
  11. return null;
  12. Map<String, Object> temp = resMap.get("layout");
  13. int viewId = (Integer) temp.get(layoutName);
  14. if(viewId != 0)
  15. {
  16. //引用皮肤包资源转化View
  17. LayoutInflater inflater =LayoutInflater.from(skinContext);
  18. view = inflater.inflate(skinContext.getResources().getLayout(viewId), null);
  19. }
  20. else
  21. {
  22. view = null;
  23. }
  24. return view;
  25. }

注:换皮肤思路详见:http://blog.csdn.net/tangnengwu/article/details/22801107

2. 訪问android 隐藏的API

Toast信息框的关闭是由系统管理的。由于hide方法是隐藏的开发人员没有办法直接调用。这样的情况下能够用发射机制获取这种方法,创建一个显示和隐藏都由开发人员控制的Toast信息框。

  1. package com.example.reflection;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. import android.content.Context;
  5. import android.util.Log;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.widget.TextView;
  9. import android.widget.Toast;
  10. public class MyToast
  11. {
  12. Context context=null;
  13. Object obj =null;
  14. public MyToast(Context context,String text)
  15. {
  16. this.context =context;
  17. Toast toast =Toast.makeText(context, text, 1);
  18. try {
  19. Field field = toast.getClass().getDeclaredField("mTN");
  20. field.setAccessible(true);
  21. obj =field.get(toast);
  22. } catch (Exception e) {
  23. // TODO: handle exception
  24. Log.d("AAA", "MyToast Exception--->"+e.toString());
  25. }
  26. }
  27. public void show()
  28. {
  29. try {
  30. //android4.0以上就要以下处理
  31. // Field mNextViewField = obj.getClass().getDeclaredField("mNextView");
  32. // mNextViewField.setAccessible(true);
  33. // LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  34. // View v = inflate.inflate(R.layout.ui_toast, null);
  35. // mNextViewField.set(obj, v);
  36. Method method =obj.getClass().getDeclaredMethod("show", null);
  37. method.invoke(obj, null);
  38. } catch (Exception e) {
  39. // TODO Auto-generated catch block
  40. Log.d("AAA", "show Exception--->"+e.toString());
  41. e.printStackTrace();
  42. }
  43. }
  44. public void hide()
  45. {
  46. try {
  47. Method method =obj.getClass().getDeclaredMethod("hide", null);
  48. method.invoke(obj, null);
  49. } catch (Exception e) {
  50. // TODO Auto-generated catch block
  51. Log.d("AAA", "hide Exception--->"+e.toString());
  52. e.printStackTrace();
  53. }
  54. }
  55. }

显示toast:

  1. MyToast toast = new MyToast(this, "反射机制!");
  2. toast.show();

隐藏toast:

toast.hide();

注意在4.0以上的版本号中,还须要对Toast 中的View进行处理,如代码中所看到的

3. 改动某些“不可改” 的系统资源

ListView组件没有提供改动高速滑块图像的API,因此不能直接改动,但可通过反射实现

  1. package com.example.reflection;
  2. import java.lang.reflect.Field;
  3. import android.content.Context;
  4. import android.graphics.drawable.Drawable;
  5. import android.util.AttributeSet;
  6. import android.widget.AbsListView;
  7. import android.widget.ListView;
  8. public class MListView extends ListView
  9. {
  10. public MListView(Context context, AttributeSet attrs)
  11. {
  12. super(context, attrs);
  13. // TODO Auto-generated constructor stub
  14. setNewDrawable(context);
  15. }
  16. private void setNewDrawable(Context context)
  17. {
  18. try {
  19. Field field = AbsListView.class.getDeclaredField("mFastScroller");
  20. field.setAccessible(true);
  21. Object obj = field.get(this);
  22. field =field.getType().getDeclaredField("mThumbDrawable");
  23. field.setAccessible(true);
  24. Drawable drawable = (Drawable)field.get(obj);
  25. drawable = context.getResources().getDrawable(R.drawable.ic_launcher);
  26. field.set(obj, drawable);
  27. } catch (Exception e) {
  28. // TODO Auto-generated catch block
  29. e.printStackTrace();
  30. }
  31. }
  32. }
  1. Field field = AbsListView.class.getDeclaredField("mFastScroller");

FastScroller.mThunbDrawable变量保存了高速滑块图像,但首先要获取AbsListView.mFastScroller变量

  1. <com.example.reflection.MListView
  2. android:id="@+id/listView1"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"
  5. android:fastScrollEnabled="true"
  6. android:scrollbars="none"
  7. >
  8. </com.example.reflection.MListView>
  1. android:fastScrollEnabled="true"

使用高速滑块

效果图例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGFuZ25lbmd3dQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

总结:

      Java中的反射机制。被称为Reflection,它同意执行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法。

Reflection机制同意程序在正在执行的过程中。利用Reflection APIs取得不论什么已知名称的类的内部信息。包含:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructors、 methods、
modifiers等。并能够在执行的过程中,动态生成Instances、变更fields内容或唤起methods。

再次基础上我们能够利用反射机制在Java程序中。动态的去调用一些protected甚至是private的方法或类,这样能够非常大程度上满足我们的一些比較特殊需求。

有关反射技术的API:

Class类:

  Class类代表着某个类的字节码。要使用反射,就须要取得相应的Class对象,然后就通过这个对象。就可解剖出类的成员变量。成员方法等等。

  获取Class类对象

//通过Class的forName()方法,此方法最为经常使用  
Class class1 = Class.forName(className);  
//通过 .class  
Class class2 = XXX.class;  
//通过对象获得  
Class class3 = new XXX().getClass(); 

  Class类的经常用法:
  getConstructor() 获取构造函数
  getMethod()  获取成员方法
  getField() 获取成员变量
  getDeclaredConstructor() 获取私有的构造函数
  getDeclaredMethod()  获取私有的成员方法
  getDeclaredField() 获取私有的成员变量

取得method对象之后

调用

  1. method.invoke(obj, null)

使用该方法

android中反射技术使用实例的更多相关文章

  1. android中反射机制

    本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或 ...

  2. c#中反射技术在Unity中的运用

    反射技术给类赋值的好处就是可以简化代码,封装的好处就显而易见了.最直接的用途就是用在在显示配置文件的时候,个人习惯性做法是做一个VO来存储需要的数据,其代码如下: internal class Bas ...

  3. java中反射讲解及实例

    Java反射机制详解 java 反射 定义 功能 示例 概要: Java反射机制详解 | |目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实 ...

  4. android中asynctask的使用实例

    参考此blog写的非常的好http://www.cnblogs.com/devinzhang/archive/2012/02/13/2350070.html MainActivity.java imp ...

  5. Android中GridView的实现实例

    实现效果: activity文件代码: package com.tmacsky; import android.app.Activity; import android.os.Bundle; impo ...

  6. android中file的使用实例

    File是android的4种存储方式的一种.File就是文件的意思一个文件,你无非是想进行读写操作.所以这就用到两个流.一个数输入流,一个是输出流.FileOutstream,和FileInputS ...

  7. .net中反射技术的应用

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Ref ...

  8. [转]Android中Xposed框架篇—利用Xposed框架实现拦截系统方法

    一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xpo ...

  9. [转载] Android中Xposed框架篇---利用Xposed框架实现拦截系统方法

    本文转载自: http://www.wjdiankong.cn/android%E4%B8%ADxposed%E6%A1%86%E6%9E%B6%E7%AF%87-%E5%88%A9%E7%94%A8 ...

随机推荐

  1. C# 条码生成类

    using System.Collections; using System.Text.RegularExpressions; namespace DotNet.Utilities { public ...

  2. swagger api文档添加jwt授权配置

    最近写的swagger文档,要加jwt授权,所以几经google终于搞定了,简简单单几行配置如下: securityDefinitions: APIKey: type: apiKey name: Au ...

  3. CodeForces 616A(水题)

    while(t--) 最后结果t=-1 #include <iostream> #include <string> #include <cstring> #incl ...

  4. PowerDesigner16导出SQL时如何添加注释

    添加注释方法 https://jingyan.baidu.com/article/47a29f24652e44c0142399c3.html 重点是修改value的值 alter table [%QU ...

  5. csharp: read excel using Aspose.Cells

    /// <summary> /// /// </summary> /// <param name="strFileName"></para ...

  6. html开发那些不好的习惯,和问题。

    最近网上看了好多html开发中那些问题和不好的习惯,顺手总结一下. 一.上下间距 在开发中你会发现你明明设置的两个p标签上下间距为20px但你实际测量中会发现他会多4~8px,这是为什么呢!如果你是老 ...

  7. [转]开源日志库<log4cplus+VS2008使用>整理

    转 开源日志库<log4cplus+VS2008使用>整理 转http://pyhcx.blog.51cto.com/713166/143549 一.简介     log4cplus是C+ ...

  8. Android dialog圆角显示及解决出现的黑色棱角

    最近在开发一个天气预报的app,看到一个比较不错友情提示,如下:                怎么样,看起来比原始的dialog好看吧.好了,做法也许有很多,我介绍下我的做法吧, 首先,我第一个想到 ...

  9. python迭代器 生成器 三元运算 列表解析

    1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...

  10. Java基础之基本数据类型的包装类型

    Java的基本数据类型的包装数据类型有多种: int Integer,short Short,boolean Boolean,float Float,double Double等等. Java包装类数 ...