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

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

首先初始化skinContext

 try {
skinContext = this.createPackageContext("com.skin",
CONTEXT_IGNORE_SECURITY|CONTEXT_INCLUDE_CODE);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
skinContext=null;
e.printStackTrace();
}

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

/**
* 取得相应包的全部资源的ID
* 存在MAP中
* @param packageName
* @return
*/
private Map<String,Map<String, Object>> getSkinResourcesId(String packageName)
{
Map<String, Object> temp = null;
Map<String,Map<String, Object>> resMap =new HashMap<String,Map<String,Object>>();
try {
//取得皮肤包中的R文件
Class<? > rClass = skinContext.getClassLoader().loadClass(packageName+".R");
//取得记录各种资源的ID的类
Class<?>[] resClass =rClass.getClasses();
String className,resourceName;
int resourceId=0;
for(int i=0;i<resClass.length;i++)
{
className = resClass[i].getName();
//取得该类的资源
Field field[] = resClass[i].getFields();
for(int j =0;j < field.length; j++)
{
resourceName = field[j].getName();
try {
resourceId = field[j].getInt(resourceName);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(resourceName!=null && !resourceName.equals(""))
{
temp =new HashMap<String, Object>();
temp.put(resourceName, resourceId);
Log.i("DDDDD", "className:"+className+" resourceName:"+resourceName+" " +
"resourceId:"+Integer.toHexString(resourceId));
}
}
//由于内部类的关系className应该是com.skin.R$layout的形式
//截掉前面的包名和.R$以方便使用
className = className.substring(packageName.length()+3);
resMap.put(className, temp);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resMap;
}

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

/**
* 获取皮肤包中的layout
* 并转化为VIEW
* @param layoutName
* @return
*/
private View getLayoutFromSkin(String layoutName)
{
View view;
if(resMap == null)
return null;
Map<String, Object> temp = resMap.get("layout");
int viewId = (Integer) temp.get(layoutName);
if(viewId != 0)
{
//引用皮肤包资源转化View
LayoutInflater inflater =LayoutInflater.from(skinContext);
view = inflater.inflate(skinContext.getResources().getLayout(viewId), null);
}
else
{
view = null;
}
return view;
}

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

2. 訪问android 隐藏的API

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

package com.example.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method; import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast; public class MyToast
{
Context context=null;
Object obj =null;
public MyToast(Context context,String text)
{
this.context =context;
Toast toast =Toast.makeText(context, text, 1);
try {
Field field = toast.getClass().getDeclaredField("mTN");
field.setAccessible(true);
obj =field.get(toast);
} catch (Exception e) {
// TODO: handle exception
Log.d("AAA", "MyToast Exception--->"+e.toString());
}
}
public void show()
{
try {
//android4.0以上就要以下处理
// Field mNextViewField = obj.getClass().getDeclaredField("mNextView");
// mNextViewField.setAccessible(true);
// LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// View v = inflate.inflate(R.layout.ui_toast, null);
// mNextViewField.set(obj, v);
Method method =obj.getClass().getDeclaredMethod("show", null);
method.invoke(obj, null);
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("AAA", "show Exception--->"+e.toString());
e.printStackTrace();
}
}
public void hide()
{
try {
Method method =obj.getClass().getDeclaredMethod("hide", null);
method.invoke(obj, null);
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("AAA", "hide Exception--->"+e.toString());
e.printStackTrace();
}
} }

显示toast:

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

隐藏toast:

toast.hide();

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

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

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

package com.example.reflection;

import java.lang.reflect.Field;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.AbsListView;
import android.widget.ListView; public class MListView extends ListView
{
public MListView(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
setNewDrawable(context);
} private void setNewDrawable(Context context)
{
try {
Field field = AbsListView.class.getDeclaredField("mFastScroller");
field.setAccessible(true);
Object obj = field.get(this);
field =field.getType().getDeclaredField("mThumbDrawable");
field.setAccessible(true);
Drawable drawable = (Drawable)field.get(obj);
drawable = context.getResources().getDrawable(R.drawable.ic_launcher);
field.set(obj, drawable);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
Field  field = AbsListView.class.getDeclaredField("mFastScroller");

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

<com.example.reflection.MListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fastScrollEnabled="true"
android:scrollbars="none"
>
</com.example.reflection.MListView>
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对象之后

调用

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. WINFORM如何实现无聚焦框的Button按钮

    当我们将一个button按钮设置如下属性时,总有一个聚焦框来困扰着我们 button1.FlatStyle = FlatStyle.Flat; 我们想要的效果是这样的: 但当使用了Tab切换焦点时 发 ...

  2. IDEA设置类注解和方法注解(详解)

    从eclipse工具到IDEA工具的转化,发现IDEA工具配置注释模板变的不一样了,不说废话了,直接开始 一.设置类注解模板(在创建类的时候自动填充模板) /** * @ProjectName: ${ ...

  3. mybatis 排坑记录

    1. mapper xml resultMap 中定义 property 时不能出现空格 否则会出现反射错误,找不到 do 对应的 set 方法

  4. POJ 1611(并查集+知识)

    并查集主要是两个过程,一个是并,一个是查 原理是用一个数组p[i]保存每个i的根节点,如果根节点一样则在同一个集合里,所以只有根节点p[i]=i; 查: int find(int x){return ...

  5. MapReduce学习

    参考文章 参考文章2 shuffle的过程分析 Hadoop学习笔记:MapReduce框架详解 谈mapreduce运行机制,可以从很多不同的角度来描述,比如说从mapreduce运行流程来讲解,也 ...

  6. 并发模型之Future设计模式

    一.Futrue模式 客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订单,不是商品本身),用户也无需等待,先去执行其他的若干操作后,再去调用服务器已经 ...

  7. python学习之老男孩python全栈第九期_day021知识点总结——包、异常处理

    一. 包 # 把解决一类问题的模块放在同一个文件夹里 -- 包 # 创建目录代码# import os# os.makedirs('glance/api')# os.makedirs('glance/ ...

  8. python_Django 实现登入功能form表单的参数接收处理

    1.创建Django工程. 参考https://www.cnblogs.com/CK85/p/10159159.html中步骤. 2.在urls.py文件中添加url分发路径 "" ...

  9. 神奇的AC

  10. Maven学习总结(七):Maven的聚合和继承

    一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 1 <modules> 2 <module>模块一</module&g ...