android 反射可以反射到另一个应用里面的类么

//访问某个属性
            Context mmsCtx = createPackageContext("com.android.lockscreen",
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
Class&?& maClass = Class.forName("com.android.lockscreen.LockScreenActivity", true, mmsCtx.getClassLoader());
Object maObject = maClass.newInstance();
Field f_mPm = maClass.getDeclaredField("TAG");
f_mPm.setAccessible(true);
Log.i(LOG_TAG, "___________________________________________obj:"+f_mPm.get(maObject));
//访问方法
Context mmsCtx = createPackageContext("com.android.lockscreen",
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
Class&?& maClass = Class.forName("com.android.lockscreen.LockScreenActivity", true, mmsCtx.getClassLoader());
Object maObject = maClass.newInstance();
Field f_mPm = maClass.getDeclaredField("TAG");
//maClass.getDeclaredMethod("", parameterTypes);
f_mPm.setAccessible(true);
Log.i(LOG_TAG, "___________________________________________obj:"+f_mPm.get(maObject));
Class[] resource = new Class[]{Context.class};
Object[] resourceObj = new Object[]{mmsCtx};
Method addsMethod = maClass.getDeclaredMethod("getLockScreenView", resource);
addsMethod.setAccessible(true);
View addsResult = (View)addsMethod.invoke(maObject, resourceObj);
Log.i(LOG_TAG, "___________________________________________addsResult:"+addsResult);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//定义被访问
public class LockScreenActivity extends Activity {
private String TAG = "LockScreenActivity";
//private LockScreen mScreen = new LockScreen(LockScreenActivity.this);
private LockScreen getLockScreenView(Context context){
Log.i(TAG, "_________________________________________context:"+context);
return new LockScreen(context);
//获取setting包的的Context
Context mmsCtx = createPackageContext("com.android.settings",
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
//使用setting的classloader加载com.android.settings.ManageApplications类
Class&?& maClass = Class.forName("com.android.settings.ManageApplications", true, mmsCtx.getClassLoader());
//创建它的一个对象
Object maObject = maClass.newInstance();
* 将私有域mPm赋值。因为mPm在SizeObserver的invokeGetSize中用到了,
* 却因为没有执行onCreate而没有初始化,所以要在此处初始化。
Field f_mPm = maClass.getDeclaredField("mPm");
f_mPm.setAccessible(true);
f_mPm.set(maObject, mmsCtx.getPackageManager());
Views(...) Comments()6453人阅读
android实现(3)
*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布
原创文章,转载请注明 ( 来自: IZZY的博客 )
动态语言:
一般认为在程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。尽管这样,JAVA有着一个非常突出的动态相关机制:反射(Reflection)。运用反射我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载在运行时才得知名称的class,获悉其完整构造方法,并生成其对象实体、或对其属性设值、或唤起其成员方法。
反射:要让Java程序能够运行,就得让Java类被Java虚拟机加载。Java类如果不被Java虚拟机加载就不能正常运行。正常情况下,我们运行的所有的程序在编译期时候就已经把那个类被加载了。
Java的反射机制是在编译时并不确定是哪个类被加载了,而是在程序运行的时候才加载。使用的是在编译期并不知道的类。这样的编译特点就是java反射。
反射的作用:
如果有AB两个程序员合作,A在写程序的时需要使用B所写的类,但B并没完成他所写的类。那么A的代码是不能通过编译的。此时,利用Java反射的机制,就可以让A在没有得到B所写的类的时候,来使自身的代码通过编译。
反射的实质:
反射就是把Java类中的各种存在给解析成相应的Java类。要正确使用Java反射机制就得使用Class(C大写) 这个类。它是Java反射机制的起源。当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。
反射机制的优点与缺点:
为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念:
静态编译:在编译时确定类型,绑定对象,即通过。
动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,降低类之间的藕合性。
一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用安装,只需要在运行时才动态的创建和编译,就可以实现该功能。它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。
Android FrameWork中的反射:
一个类中的每个成员都可以用相应的反射API的一个实例对象来表示——反射机制。
了解这些,那我们就知道了,我们可以利用反射机制在Java程序中,动态的去调用一些protected甚至是private的方法或类,这样可以很大程度上满足我们的一些比较特殊需求。例如Activity的启动过程中Activity的对象的创建。
以下代码位于ActivityThread中:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
。。。。。。
Activity activity = null
java.lang.ClassLoader cl = r.packageInfo.getClassLoader()
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent)
StrictMode.incrementExpectedActivityCount(activity.getClass())
r.intent.setExtrasClassLoader(cl)
r.intent.prepareToEnterProcess()
if (r.state != null) {
r.state.setClassLoader(cl)
。。。。。。
上面代码可知Activity在创建对象的时候调用了mInstrumentation.newActivity();
以下代码位于Instrumentation中:
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
最终在newActivity()里返回的是利用cl.loadClass返回的Activity对象。可知,Activity对象的创建是通过反射完成的。java程序可以动态加载类定义,而这个动态加载的机制就是通过ClassLoader来实现的,所以可想而知ClassLoader的重要性如何。
ClassLoader和DexClassLoader
上面说到JAVA的动态加载的机制就是通过ClassLoader来实现的,ClassLoader也是实现反射的基石。ClassLoader是JAVA提供的一个类,顾名思义,它就是用来加载Class文件到JVM,以供程序使用的。
但是问题来了,ClassLoader加载文件到JVM,但是Android是基于DVM的,用ClassLoader加载文件进DVM肯定是不行的。于是Android提供了另外一套加载机制,分别为 dalvik.system.DexClassLoader 和 dalvik.system.PathClassLoader,区别在于 PathClassLoader 不能直接从 zip 包中得到 dex,因此只支持直接操作 dex 文件或者已经安装过的 apk(因为安装过的 apk 在 cache 中存在缓存的 dex 文件)。而 DexClassLoader 可以加载外部的 apk、jar 或 dex文件,并且会在指定的 outpath 路径存放其 dex 文件。
ClassLoader在JAVA中的应用
下面利用反射来调用另一个类中的方法
package com.
public class Test {
public Test(String s) {
public void display() {
System.out.println(s);
package com.
import java.lang.reflect.C
public class Client {
public static void main(String[] s) {
Class clazz = ClassLoader.getSystemClassLoader().loadClass(
"com.izzy.Test");
Constructor constructor = clazz.getConstructor(String.class);
Object obj = constructor.newInstance("I AM IZZY");
Method method = clazz.getMethod("display", null);
method.invoke(obj, null);
} catch (Exception e) {
e.printStackTrace();
DexClassLoader在Android中的应用
以一个例子来说明DexClassLoader用法(本例采用两个已安装的Apk),现在有两个Apk:Share和Test,利用Test来调用Share 里面的方法。
首先在Share apk中定义Share类,其中有一个display()方法提供给远程调用
public class Share {
public void display(String s) {
Log.e("IZZY", s);
接着在manifest文件中配置action和category,方便调用这找到
android:name=".MainActivity"
android:theme="@android:style/Theme.Light.NoTitleBar"&
android:name="com.IZZY"/&
android:name="android.intent.action.MAIN" /&
android:name="android.intent.category.DEFAULT" /&
android:name="android.intent.category.LAUNCHER" /&
接下来就是在Test Apk中编写调用代码了
public void getFromRemote() {
Intent intent = new Intent("com.IZZY");
PackageManager pm = getPackageManager();
List&ResolveInfo& resolveInfos = pm.queryIntentActivities(intent, 0);
ResolveInfo resolveInfo = resolveInfos.get(0);
ActivityInfo activityInfo = resolveInfo.activityI
String packageName = activityInfo.packageN
String dexPath = activityInfo.applicationInfo.sourceD
String dexOutputDir = getApplicationInfo().dataD
String nativeLibraryDir = activityInfo.applicationInfo.nativeLibraryD
ClassLoader classLoader = getClassLoader();
DexClassLoader dcl = new DexClassLoader(dexPath,dexOutputDir,nativeLibraryDir,classLoader);
Class&?& clazz = dcl.loadClass(packageName + ".Share");
Constructor&?& constructor = clazz.getConstructor();
Object o = constructor.newInstance();
Method display = clazz.getMethod("display", String.class);
display.invoke(o, "I AM IZZY");
} catch (Exception e) {
e.printStackTrace();
在该调用方法中首先利用Intent查询到目标activityInfo,然后利用查询到的activityInfo得到目标Apk的包名,目标Apk所在的apk或者jar存放的路径dexPath,目标Apk所使用的C/C++库存放路径nativeLibraryDir。然后利用这些参数实例化DexClassLoader加载器。之后反射调用目标类中的方法。(ps:此处使用的目标Apk是已经安装过的,因此采用Intent查询来拿到dexPath和nativeLibraryDir,如果是未安装过的jar包或Apk,则直接传入该jar包活Apk的文件存放路径和C/C++库存放路径)。
运行结果:
从结果看,调用者Apk拿到了目标Apk的方法并成功执行。
DexClassLoaderde 在Android中的使用场景
上面是是使用的已经安装过的Apk,如果采用未安装过的jar包或者Apk,则实例化DexClassLoader的时候把相应路径改为需要加载的jar包或者Apk路径亦可拿到结果。这就使得DexClassLoaderde可以应用在HotFix(热修复),动态加载框架等等 一些基于插件化的架构中。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:33171次
排名:千里之外
原创:22篇
评论:10条
(3)(5)(7)(1)(2)(3)(1)Android反射机制实例 - 沉淀之路—Android - ITeye博客
博客分类:
对程序员来说,放假只是换了一个写代码的地方!
看一下Java(Android)里面的反射怎么用:
一、先来定义两个类(一个父类,一个子类):
package com.zwq.
public abstract class Person {
String name = "";
private int age = 0;
public int fPubVar = 0;
abstract void getPhone();
public Person() {
System.out.println("I am Farther");
int myAge() {
return 50;
String myName() {
return "Father";
public void callSun() {
getPhone();
priMethod(25);
private void priMethod(Integer a) {
System.out.println("I am priMethod , Dont call me! age " + age);
public void hideMethod(String name) {
System.out.println("I am hideMethod , Dont call me! name:" + name
age:" + age);
package com.zwq.
import java.util.O
import java.util.O
public class Man extends Person implements Observer {
private int age = 0;
private String var1 = "I am var1";
public int var2 = 20;
public Man() {
System.out.println("I am Man" + var1);
public int myAge() {
return 28;
public String myName() {
return "Jerome";
private void getName(){
System.out.println("I am Jerome");
private void getAge(){
System.out.println("I am "+age);
void getPhone() {
System.out.println("I am sun , My age is " + age + "___" + var2);
public void update(Observable o, Object arg) {
以上两个类只是为了测试,不用关心具体实现代码,只要知道有private变量和方法,protected变量和方法,public变量和方法。重点在下面:
二、利用反射,调用上面的类:
package com.zwq.
import java.lang.reflect.F
import java.lang.reflect.M
public class Main {
public static void main(String[] args) {
getInfo();
callSpuerMethod();
callCurrentMethod();
callOtherMethod();
static void getInfo() {
Man r = new Man();
Class&?& temp = r.getClass();
System.out.println("反射类中所有公有的属性");
Field[] fb = temp.getFields();
for (int j = 0; j & fb. j++) {
Class&?& cl = fb[j].getType();
System.out.println("fb:" + cl + "___" + fb[j].getName());
System.out.println("反射类中所有的属性");
Field[] fa = temp.getDeclaredFields();
for (int j = 0; j & fa. j++) {
Class&?& cl = fa[j].getType();
System.out.println("fa:" + cl + "____" + fa[j].getName());
System.out.println("反射类中所有的方法");
Method[] fm = temp.getMethods();
for (int i = 0; i & fm. i++) {
System.out.println("fm:" + fm[i].getName() + "____"
+ fm[i].getReturnType().getName());
System.out.println("反射类中所有的接口");
Class&?&[] fi = temp.getInterfaces();
for (int i = 0; i & fi. i++) {
System.out.println("fi:" + fi[i].getName());
System.out.println("反射类中私有属性的值");
Field f = temp.getDeclaredField("var1");
f.setAccessible(true);
String i = (String) f.get(r);
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
* 修复父类变量,调用父类方法
static void callSpuerMethod() {
Man r = new Man();
// 修改私有变量;
Field f = r.getClass().getSuperclass().getDeclaredField("age");
f.setAccessible(true);
f.set(r, 20);
// 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;
Method mp = r.getClass().getSuperclass()
.getDeclaredMethod("priMethod", Integer.class);
mp.setAccessible(true);
mp.invoke(r, 18);
// 调用隐藏方法
Method m = r.getClass().getSuperclass()
.getMethod("hideMethod", String.class);
m.setAccessible(true);
m.invoke(r, "Jerome");
} catch (Exception e) {
e.printStackTrace();
* 修复子类变量,调用子类方法
static void callCurrentMethod() {
Man r = new Man();
// 修改私有变量;
Field f = r.getClass().getDeclaredField("age");
f.setAccessible(true);
f.set(r, 20);
// 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;
Method mp = r.getClass().getDeclaredMethod("getName");
mp.setAccessible(true);
mp.invoke(r);
// 调用隐藏私有方法
Method m = r.getClass().getDeclaredMethod("getAge");
m.setAccessible(true);
m.invoke(r);
} catch (Exception e) {
e.printStackTrace();
* 用Class.forName加载类及实例化
static void callOtherMethod() {
// Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象
// Class.forName(xxx.xx.xx) 的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
Class&?& cl = Class.forName("com.zwq.test.Man");
Object r = cl.newInstance();
// 修改私有变量;
Field f = cl.getDeclaredField("age");
f.setAccessible(true);
f.set(r, 20);
// 调用私有方法,必须要用getDeclaredMethod,而不能用getMethod;
Method mp = cl.getDeclaredMethod("getName");
mp.setAccessible(true);
mp.invoke(r);
// 调用隐藏私有方法
Method m = cl.getDeclaredMethod("getAge");
m.setAccessible(true);
m.invoke(r);
} catch (Exception e) {
e.printStackTrace();
三、最后贴一个Android里面的具体事例:
* 获得包的大小
* @param pkgName
* @throws Exception
public void queryPacakgeSize(String pkgName) throws Exception {
if (pkgName != null) {
// 使用放射机制得到PackageManager类的隐藏函数getPackageSizeInfo
PackageManager pm = getPackageManager(); // 得到pm对象
// 通过反射机制获得该隐藏函数
Method getPackageSizeInfo = pm.getClass().getDeclaredMethod(
"getPackageSizeInfo", String.class,
IPackageStatsObserver.class);
// 调用该函数,并且给其分配参数 ,待调用流程完成后会回调PkgSizeObserver类的函数
getPackageSizeInfo.invoke(pm, pkgName, new PkgSizeObserver());
// 停止主线程让PackageStats对象获得数据
Thread.sleep(8);
} catch (Exception ex) {
// Log.e("TAG", "NoSuchMethodException") ;
ex.printStackTrace();
// 抛出异常
关于反射的使用,基本就这些了,代码注释已经很详细了,就不需要多余的说明了,想了解反射的原理,建议大家看源码!
参考:/crazypebble/archive//2014582.html
浏览: 860243 次
来自: 深圳
咋用啊,搞不懂
非常感谢!!!!!!!!!
请问 sendBuffer
sendCmds 里面传入的数据 ...
有没有demo?主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
傻丫头和高科技产物小心翼翼的初恋
个人大数据技术博客:
人生得意须尽欢,莫使金樽空对月。
一只文艺范的软件攻城狮,Keep Learn,Always.}

我要回帖

更多关于 android反射获取类名 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信