android中反射技术使用实例
在计算机科学领域。反射是指一类应用,它们能够自描写叙述和自控制。也就是说,这类应用通过採用某种机制来实现对自己行为的描写叙述(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类对象
取得method对象之后
调用
method.invoke(obj, null)
使用该方法
android中反射技术使用实例的更多相关文章
- android中反射机制
本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或 ...
- c#中反射技术在Unity中的运用
反射技术给类赋值的好处就是可以简化代码,封装的好处就显而易见了.最直接的用途就是用在在显示配置文件的时候,个人习惯性做法是做一个VO来存储需要的数据,其代码如下: internal class Bas ...
- java中反射讲解及实例
Java反射机制详解 java 反射 定义 功能 示例 概要: Java反射机制详解 | |目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实 ...
- android中asynctask的使用实例
参考此blog写的非常的好http://www.cnblogs.com/devinzhang/archive/2012/02/13/2350070.html MainActivity.java imp ...
- Android中GridView的实现实例
实现效果: activity文件代码: package com.tmacsky; import android.app.Activity; import android.os.Bundle; impo ...
- android中file的使用实例
File是android的4种存储方式的一种.File就是文件的意思一个文件,你无非是想进行读写操作.所以这就用到两个流.一个数输入流,一个是输出流.FileOutstream,和FileInputS ...
- .net中反射技术的应用
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Ref ...
- [转]Android中Xposed框架篇—利用Xposed框架实现拦截系统方法
一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xpo ...
- [转载] 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 ...
随机推荐
- unity项目git管理
Unity设置 (关键) Edit -> Project Settings -> Editor -> Version Control Mode 开启 Visible Meta Fil ...
- git merge后,后悔了如何回退
今天将feature分支的代码merge到develop分支后我后悔了,因为feature分支的功能还没有全部开发完成,我在feature分支上commit是可以的,但是这之后我又把它merge到了d ...
- CF898A Rounding
题意翻译 给你一个数字,将其“四舍六入”,末尾为5舍去或进位都可,求最终的数字. 题目描述 Vasya has a non-negative integer n n n . He wants to r ...
- 基于Spark GraphX计算二度关系
关系计算问题描述 二度关系是指用户与用户通过关注者为桥梁发现到的关注者之间的关系.目前微博通过二度关系实现了潜在用户的推荐.用户的一度关系包含了关注.好友两种类型,二度关系则得到关注的关注.关注的好友 ...
- Java 基础:数组
一.数组声明: int[] x; int x[]; 在Java中一般使用前者,机把int[]看做一个类型,C++中只能后者 二.数组初始化: 直接提供值: int[] x = {1, 3, 4}; i ...
- cf1090 I.Minimal Product(贪心)
题意 题目链接 给出长度为\(n\)的序列\(a\),序列中的元素取值为\([-2e9, 2e9]\) 找到两个位置\((i, j) (i <j, a[i] < a[j])\),最小化\( ...
- angular排序
说点小案例angular的排序 <!DOCTYPE html> <html ng-app="mk"> <head> <meta chars ...
- Java中int与Integer的区别
转自https://www.cnblogs.com/guodongdidi/p/6953217.html import java.lang.Integer; public class intDemo{ ...
- 【vue入门】日志demo,增删改查的练习(无vuex版本)
安装 1. 确定电脑已装node和npm 出现版本号则说明电脑已经安装好node和npm2. 创建一个基于webpack的项目 3. 在项目里安装依赖 4. 运行 配置路由为了动态渲染各个页面的组 ...
- Android 黑色样式menu
效果图: