android中反射技术使用实例
来源:互联网 发布:淘宝商城分销平台 编辑:程序博客网 时间:2024/04/27 10:07
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 exceptionLog.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 blockLog.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 blockLog.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 stubsetNewDrawable(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 blocke.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"使用快速滑块
效果图如下:
总结:
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中反射技术使用实例
- android中反射技术使用实例
- android中反射技术使用实例
- Android中Java反射技术的使用示例
- Android中Java反射技术
- Android 中利用反射技术
- Android 中使用反射
- Android 中利用反射技术实现加减乘除
- Android 中反射的使用
- System.Reflection 反射技术实例.
- c# 反射使用实例
- c# 反射使用实例
- java反射使用实例
- java使用反射实例
- Android 反射技术
- Java中反射技术
- SVN 多人修改,如何管理 关于版本的问题
- Read-Write lock 看可以,不过看的时候不能写
- ORACLE EXP不能导出空表的原因分析及解决方法
- digestion of file system of minix 3.1.8
- 解读linux对string.h函数的实现
- android中反射技术使用实例
- Java快速复制文件
- 预处理预编译(C++)
- HOWTO: Be more productive
- MFC从多个EDIT中读取和保存文件
- 浅谈Java中的static
- vi替换操作
- 不为人知的秘密
- Android BaseAdapter介绍和优化