java反射调用方法可以传非基本类型吗如对象、接口

java反射调用方法可以传非基本类型吗如对象、接口,第1张

可以的,参数类型是没有限制的。通过以下代码可以证明。

接口

public interface MyInterface {

    void print();

}

实现类:

public class MyInterfaceImpl implements MyInterface {

    @Override

    public void print() {

        Systemoutprintln("interfaceImpl");

    }

}

通过反射调用方法

import javalangreflectMethod;

public class Test {

    public static void main(String[] args) throws Exception {

        Test instance = TestclassnewInstance();

        Method method = TestclassgetDeclaredMethod("test", MyInterfaceclass);

        MyInterface myInterface = new MyInterfaceImpl();

        methodinvoke(instance, myInterface);

    }

    public void test(MyInterface myInterface) {

        myInterfaceprint();

    }

}

一、前言

在android系统源码中,有很多的api是隐藏的,在eclipse中通过sdk是无法访问到的。这些api有的是整个类/接口、有的是某个具体的方法、或者变量,在源码中通过文档注释内的“@hide”字符进行标识。如果我们需要去访问这些被hide的方法、类,可以采用如下两种方式:

1、在源码环境下进行访问,即将我们的工程放到源码下进行编译,这样是可以访问的;

2、通过java的反射机制

二、场景描述

这里讲述的是在eclipse下直接通过反射机制来访问系统隐藏api。举例如下:

androidappActivityManagerNative类定义了一个setActivityController(IActivityController watcher)方法,该方法通过参数IAcitivityController设置一个监听器,用来监听系统启动某个Activity。当系统启动某个Activity时,会调用IAcitivityController的回调方法。

在工程中可以通过获取ActivityManagerNative对象并生成一个IActivityController实例作为setActivityController()的参数传递过去,从而达到在工程中监听到系统Activity的启动。

ActivityManagerNativejava和IAcitivityControlleraidl均为hide api,如下:

[java] view plaincopy

package androidapp;

/ {@hide} /

public abstract class ActivityManagerNative extends Binder implements IActivityManager{

/

Retrieve the system's default/global activity manager

/

static public IActivityManager getDefault() {

return gDefaultget();

}

public void setActivityController(IActivityController watcher) throws RemoteException{}

}

package androidapp;

import androidcontentIntent;

/

Testing interface to monitor what is happening in the activity manager

while tests are running Not for normal application development

{@hide}

/

interface IActivityController

以上类都有“@hide”标识,所以需要通过反射的机制来进行访问。ActivityManagerNative对象可通过反射和该类的静态方法getDefault()获取到,再通过setActivityController方法设置监听器。但IActivityController也是内部hide aidl文件,如何继承该接口并实例化呢?

解决方案:把系统内的IActivityControlleraidl文件在我们自己的工程里按照同样的包结构创建一份,在程序中继承该接口,在调用setActivityController时传入该实例即可。

三、实现过程

1、拷贝系统内IActivityControlleraidl到工程中,与系统内该文件包结构保持一致:

2、程序中实现该接口:

[java] view plaincopy

private class ActivityController extends IActivityControllerStub {

public boolean activityStarting(Intent intent, String pkg) {

return true;

}

public boolean activityResuming(String pkg) {

return true;

}

public int appEarlyNotResponding(String processName, int pid,

String annotation) {

return 0;

}

public boolean appCrashed(String processName, int pid, String shortMsg,

String longMsg, long timeMillis, String stackTrace) {

return false;

}

public int appNotResponding(String processName, int pid,

String processStats) {

return 0;

}

}

3、通过反射获取ActivityManagerNative对象并调用方法setActivityController进行监听器设置:

[java] view plaincopy

private void setActivityController() {

try {

Class<> cActivityManagerNative = Class

forName("androidappActivityManagerNative");

Method mGetDefault = cActivityManagerNativegetMethod("getDefault",

null);

Object oActivityManagerNative = mGetDefaultinvoke(null, null);

Class<> i = ClassforName("androidappIActivityController$Stub");

Method mSetActivityController = cActivityManagerNativegetMethod(

"setActivityController",

ClassforName("androidappIActivityController"));

mSetActivityControllerinvoke(oActivityManagerNative,

new ActivityController());

} catch (ClassNotFoundException e) {

eprintStackTrace();

} catch (NoSuchMethodException e) {

eprintStackTrace();

} catch (IllegalArgumentException e) {

eprintStackTrace();

} catch (IllegalAccessException e) {

eprintStackTrace();

} catch (InvocationTargetException e) {

eprintStackTrace();

}

当然可以,

A已知dll的路径和文件名,但不知里面的类名,只知道里面必定有某类实现了接口I

可以让B设计一个方法,返回这个接口I

这样A的程序里面通过调用B的这个方法,来得到自己需要的接口实现类对象

可以实现,很方便。我去找个例子贴给你

Class daoFactoryClass = ClassforName(daoName);

//daoName是DAOFactory实现类的名字

// types of the constructor arguments

Class[] constrArgs = {Propertiesclass};

Object[] args = {daoProps};

//daoProps是Properties类型,它的内容来自一个配置文件

// get Constructor of this class with matching parameter types

Constructor<IDAOFactory> constructor = daoFactoryClassgetConstructor(constrArgs);

thisfactory = constructornewInstance(args);

以上就是关于java反射调用方法可以传非基本类型吗如对象、接口全部的内容,包括:java反射调用方法可以传非基本类型吗如对象、接口、如何生成内部hide接口实例并通过反射作为参数进行传递、请教关于vb.net(最好)或c#接口实现和反射的问题。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/9299811.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-26
下一篇2023-04-26

发表评论

登录后才能评论

评论列表(0条)

    保存