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 ...
随机推荐
- android drawable size
================
- unity GUI Layout 组件(全)
[expand 扩张][fitter 装配工] [envelope 信封,包装] Layout 布局 三种. Horizontal Layout Group 水平布局 Padding:内边距,单位 ...
- 17、多线程 (Thread、线程创建、线程池)
进程概念 *A:进程概念 *a:进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行, 即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程的概念 *A:线程的概念 *a ...
- 10、List、Set
List接口 List接口的特点 *A:List接口的特点: a:它是一个元素存取有序的集合. 例如,存元素的顺序是11.22.33.那么集合中,元素的存储就是按照11.22.33的顺序完成的). b ...
- Linux(Ubuntu)下MySQL的安装
1)首先检查系统中是否已经安装了MySQL 在终端里面输入 sudo netstat -tap | grep mysql 若没有反映,没有显示已安装结果,则没有安装.若如下显示,则表示已经安装 2)如 ...
- JavaWeb学习总结(三):Servlet开发(一)
一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...
- 简易搭建git仓库、关联远程和本地仓库方法。克隆仓库方法。同一台电脑上创建两个git ssh key方法。
一,在github上建仓库 react-js-antd-demo: 二:将远程仓库与本地仓库关联 git remote add origin git@github.com:begin256/react ...
- Django——REST framework
1. 什么是REST REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度类审 ...
- MessageFormat使用记录
1.日志里面需要记录入参,之前一般使用StringUtils.formt()方法,但是如果入参含有空值,就会报错.这个时候可以使用MessageFormat方法.用法 format(String pa ...
- jquery使页面滚动到底部
function scrollToEnd(){//滚动到底部 var h = $(document).height()-$(window).height(); $(document).scrollTo ...