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 ...
随机推荐
- 启动Hadoop时候datanode没有启动的原因及解决方案
有时候我们start-dfs.sh启动了hadoop但是发现datanode进程不存在 一.原因 当我们使用hadoop namenode -format格式化namenode时,会在namenode ...
- MAC 系统 各种操作
Part1:MAC如何打开活动监控器 1.第一种方法: 2.第二种方法 然后直接拖到dock中 Part2:Terminal 中的操作 一.如何开启apache 在终端输入sudo apachectl ...
- spring boot2 使用log4j2
spring boot默认使用的是logback,看到好多地方说logback比log4j耗性能,具体么我也没试过,不过个人还是log4j用得更多. 先看pom依赖 <dependency> ...
- 【SSH网上商城项目实战29】使用JsChart技术在后台显示商品销售报表
转自:https://blog.csdn.net/eson_15/article/details/51506334 这个项目终于接近尾声了,注册功能我就不做了,关于注册功能我的另一篇博客详细的介绍 ...
- C# 调用C++DLL 类型转换
内容转自网上····这里做 备份··· 原文链接: http://blog.csdn.net/miss_easy/article/details/52470964 /C++中的DLL函数原型为 //e ...
- 理解域名插槽:slot-scope
作用域插槽 | 带数据的插槽 最后,就是我们的作用域插槽.这个稍微难理解一点.官方叫它作用域插槽,实际上,对比前面两种插槽,我们可以叫它带数据的插槽.什么意思呢,就是前面两种,都是在组件的templa ...
- c++实现全密码生成
这里所谓的“全密码”指的是指定字符串中所有可能出现的密码.以字符串“0123456789”为例,可能出现的2位密码会有100个,即L^N个.(L代表字符串的长度,N代表要生成密码的位数). 第一种方法 ...
- cf1060E. Sergey and Subway(树形dp)
题意 题目链接 Sol 很套路的题 直接考虑每个边的贡献,最后再把奇数点的贡献算上 #include<bits/stdc++.h> #define Pair pair<int, in ...
- Swiper轮播图
今天咱们来说一下.Swiper轮播图. 超级简单的: 翠花,上代码: <!DOCTYPE html> <html lang="en"> < ...
- 须知的css——margin不重叠的情形
margin重叠 摘自css2.1规范中文版 CSS中,两个或者多个盒(可能但不一定是兄弟)的相邻的margin会被结合成一个margin.Margin按这种方式结合叫重叠(collapse),产生的 ...