java 反射调用带回调接口的函数

这篇博客探讨了在Android开发中如何使用Java反射来调用带有回调接口的SDK方法,以此解决SDK资源未引入导致的崩溃问题。文中通过一个移动支付SDK的示例,详细介绍了导入SO文件、invokeStaticMethod的实现、重点方法invokeContainsInterfaceStaticMethod的实现,以及如何捕获回调接口参数的CarrotPayCallbackMethodInterceptor类的实现。

        在android开发中会遇到各种SDK的接入,很是麻烦。最初在想能不能把所有的SDK都融合到一个当中,发现有点异想天开。但是也可以解决SDK资源不小心没有引入,导致程序调用接口崩溃问题。经过查资料,还是写了一个小Demo,仅供参考!很早之前写的了,估计移动基地SDK,有变动,不过道理是一样的。

        仅以移动基地SDK举例。

1.移动支付需要的SO文件导入。

public class CarrotApplication extends Application {
	//是否含有移动支付SDK
	boolean useCMBilling = false;
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		try {
            Class.forName("cn.cmgame.billing.api.GameInterface");
            useCMBilling = true;
        } catch (ClassNotFoundException ignored) {

        }
		if(useCMBilling){
			System.loadLibrary("megjb");
		}
	}
}

2.初始化移动基地支付
protected void init_cmcc(String app_name, String app_company,
			String telphone_number) {
		try {
			Object [] cmcc_init_obj = {CarrotPaySDK.mContext,app_name,app_company,telphone_number};
			Class<?> [] classparam = {Activity.class,String.class,String.class,String.class};
			cfcaim.invokeStaticMethod("cn.cmgame.billing.api.GameInterface","initializeApp",cmcc_init_obj,classparam);
		} catch (Exception e) {
			// TODO: handle exception
			Log.e("init_cmcc异常捕捉", "异常:"+e.toString());
		}
	}

3.上面 invokeStaticMethod 的实现

<
### Java 中显式调用的概念及相关方法 #### 显式调用概述 在 Java 编程语言中,“显式调用”通常指的是通过特定的方式主动触发某些行为或操作,而不是依赖于默认机制。这可以涉及对象的创建、方法的执行以及垃圾回收等。 --- #### 1. **显式创建对象** Java 提供了多种方式来显式地创建对象。最常见的是使用 `new` 关键字直接实例化类的对象[^1]: ```java // 使用 new 创建对象 MyClass obj = new MyClass(); ``` 另一种方式是利用反射机制中的 `newInstance()` 方法动态创建对象: ```java // 反射创建对象 Class<?> clazz = Class.forName("com.example.MyClass"); Object instance = clazz.getDeclaredConstructor().newInstance(); ``` 这种方式特别适用于运行时才知道具体类型的场景。 --- #### 2. **显式调用垃圾回收 (GC)** 虽然 JVM 自动管理内存分配和释放,但在特殊情况下可以通过调用 `Runtime.gc()` 或 `System.gc()` 来建议 JVM 执行垃圾回收[^2]: ```java // 建议 JVM 进行垃圾回收 System.gc(); // 查看当前可用内存 long freeMemory = Runtime.getRuntime().freeMemory(); System.out.println("Free Memory: " + freeMemory); ``` 需要注意的是,这种请求并不一定会立即生效,因为最终决定权在于 JVM 的实现。 --- #### 3. **通过反射获取注解并显式处理** 自 Java 8 起,在 `java.lang.reflect.Executable` 类中引入了新的 API 支持更灵活的操作,比如通过 `getAnnotatedReceiverType()` 获取接收者的注解类型[^3]: ```java import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedType; import java.lang.reflect.Method; public class ReflectionExample { public static void main(String[] args) throws Exception { // 获取目标方法 Method method = Calculator.class.getMethod("calc"); // 获取接收者类型的注解 AnnotatedType receiverType = method.getAnnotatedReceiverType(); // 判断是否存在 @ServerObject 注解 boolean hasAnnotation = receiverType.isAnnotationPresent(ServerObject.class); System.out.println("@ServerObject present? " + hasAnnotation); } } @interface ServerObject {} class Calculator { public void calc() {} } ``` 上述代码展示了如何通过反射技术检查某个方法是否具有指定的注解。 --- #### 4. **显式调用构造函数** 当子类需要访问父类的不同构造函数时,必须通过 `super(...)` 实现显式的调用[^5]。如果忽略这一点,则可能会引发编译错误提示“隐式超级构造函数未定义”。 下面是一个典型的例子: ```java class Parent { String name; // 定义参构造器 Parent(String name) { this.name = name; } // 如果不提供无参构造器,默认不会存在 } class Child extends Parent { // 子类构造器需显式调用父类构造器 Child(String childName, String parentName) { super(parentName); // 显式调用父类构造器 System.out.println("Child constructor called with name: " + childName); } } public class Main { public static void main(String[] args) { Child c = new Child("Tom", "Jerry"); } } ``` 在此案例中,由于父类仅提供了有参构造器而没有无参版本,因此子类必须手动调用它以完成初始化过程。 --- #### 5. **显示打印日志信息** 为了调试目的,开发者经常会在程序中加入一些输出语句以便观察内部状态变化情况[^4]: ```java class Animal { private String name; // 构造器 public Animal(String name) { this.name = name; System.out.println("Animal一个参数的构造器,name参数:" + name); } } ``` 这里每次实例化一个新的动物对象都会自动记录其名称属性值到控制台窗口上。 --- ### 总结 以上介绍了几种常见的关于 Java “显式调用”的应用场景及其对应的实际编码技巧。无论是基础层面还是高级特性方面都体现了灵活性与强大功能相结合的特点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值