android中反射技术使用实例

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

1.通过反射技术可以访问到其他包名下数据方法等,这些为一些APK换皮肤提供了方便

首先初始化skinContext


?
1
2
3
4
5
6
7
8
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
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
      * 取得对应包的所有资源的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= "" block= "" e.printstacktrace();= "" (illegalaccessexception= "" 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; 
         } </resclass.length;i++)></string,map<string,object></string,map<string,></string,></string,map<string,>

最后通过资源ID和skinContext可以访问到指定包下的所有资源,例如要访问layout
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
      * 获取皮肤包中的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; 
     }  </string,>

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


2. 访问android 隐藏的API

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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:
?
1
2
MyToast toast = new MyToast( this , "反射机制!" );
toast.show();
隐藏toast:

toast.hide();

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


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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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();
         }
     }
 
}
?
1
Field  field = AbsListView. class .getDeclaredField( "mFastScroller" );
FastScroller.mThunbDrawable变量保存了快速滑块图像,但首先要获取AbsListView.mFastScroller变量


?
1
2
<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>


?
1
android:fastScrollEnabled= "true"
使用快速滑块

效果图如下:

\


总结:

Java中的反射机制,被称为Reflection,它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法。Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的内部信息,包括:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructZ喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcnOhoiBtZXRob2RzoaIKIG1vZGlmaWVyc7XIo6yyor/J0tTU2ta00NC1xLn9s8zW0KOstq/MrMn6s8lJbnN0YW5jZXOhorHkuPxmaWVsZHPE2sjdu/K7vcbwbWV0aG9kc6Gj1Nm0zrv5tKHJz87Sw8e/ydLUwPvTw7e0yeS7+tbG1NpKYXZhs8zQ8tbQo6y2r8ystcTIpbX308PSu9CpcHJvdGVjdGVkyfXWwcrHcHJpdmF0ZbXEt723qLvywOCjrNXi0fm/ydLUuty087PMtsjJz8L61+PO0sPHtcTSu9Cpsci9z8zYyuLQ6MfzoaM8YnI+CjwvcD4KPHA+PGJyPgo8L3A+CjxwPtPQudi3tMnkvLzK9bXEQVBJOjwvcD4KPHA+Q2xhc3PA4KO6PC9wPgogIENsYXNzwOC0+rHt18XEs7j2wOC1xNfWvdrC66Os0qrKudPDt7TJ5KOsvs3Q6NKqyKG1w7bU06a1xENsYXNzttTP86OsyLu6877Nzai5/dXiuPa21M/zo6y+zb/JveLGyrP2wOC1xLPJ1LGx5MG/o6yzydSxt723qLXItcihozxicj4KICC78cihQ2xhc3PA4LbUz/M8YnI+Ci8vzai5/UNsYXNztcRmb3JOYW1lKCm3vbeoLLTLt723qNfuzqqzo9PDICAKQ2xhc3MgY2xhc3MxID0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOyAgCi8vzai5/SAuY2xhc3MgIApDbGFzcyBjbGFzczIgPSBYWFguY2xhc3M7ICAKLy/NqLn9ttTP87vxtcMgIApDbGFzcyBjbGFzczMgPSBuZXcgWFhYKCkuZ2V0Q2xhc3MoKTsgIDxicj4KCjxicj4KCiAgQ2xhc3PA4LXEs6PTw7e9t6ijujxicj4KCiAgZ2V0Q29uc3RydWN0b3IoKSC78cihubnU7Lqvyv0KICBnZXRNZXRob2QoKSAgu/HIobPJ1LG3vbeoCiAgZ2V0RmllbGQoKSC78cihs8nUsbHkwb8KICBnZXREZWNsYXJlZENvbnN0cnVjdG9yKCkgu/HIocu909C1xLm51Oy6r8r9CiAgZ2V0RGVjbGFyZWRNZXRob2QoKSAgu/HIocu909C1xLPJ1LG3vbeoCiAgZ2V0RGVjbGFyZWRGaWVsZCgpILvxyKHLvdPQtcSzydSxseTBvwo8cD7IobXDbWV0aG9kttTP89auuvM8L3A+CjxwPrX308M8L3A+CjxwcmUgY2xhc3M9"brush:java;">method.invoke(obj, null)使用该方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与国已互相成为双方最大的交易伙伴。国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占国外贸总值的15.4%。在过去20余年,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值