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 的实现

/**
	 * 执行某个类的静态方法
	 * @param	className		类名
	 * @param	methodName		方法名
	 * @param	oArray			方法参数
	 * @param	paramTypeArray		构造参数类型
	 * @author liudb
	 * */
	public Object invokeStaticMethod(String className, String methodName,
			Object[] oArray,Class<?> [] paramTypeArray) throws Exception {
		Class<?> ownerClass = Class.forName(className);
		Method method = ownerClass.getMethod(methodName, paramTypeArray);
		return method.invoke(ownerClass, oArray);
	}

4.调用支付接口

/**
	 * 执行移动支付
	 * @param		isUsesim		sim卡是否可用
	 * @param		isRepeat		计费点是否可重复
	 * @param		index			计费点编号
	 * @param		order			订单号
	 * @param 		callback		支付回调
	 */
	protected void cmcc_pay(boolean isUsesim,boolean isRepeat,String index,String order,final CarrotPayCallBack callback){
		try {
			//这里的 callback  是自定义的回调函数,会在步骤7里介绍
                        cmcc_PayendHandler = new CarrotHandler(CarrotPaySDK.mContext){
				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					super.handleMessage(msg);
                                        //这里处理返回结果
                                        callback.onPayEnd(msg.what);
				}
			};
			// 传入参数
			Object [] cmcc_pay_param = {CarrotPaySDK.mContext,isUsesim,isRepeat,index,order,new Object()};
			// 参数对应的TYPE
			Class<?> [] cmcc_pay_paramtyp = {Context.class,boolean.class,boolean.class,String.class,String.class,Object.class};
			// "IPayCallback" 是移动支付的回调函数名
			cfcaim.invokeContainsInterfaceStaticMethod("cn.cmgame.billing.api.GameInterface", "doBilling", cmcc_pay_param,cmcc_pay_paramtyp,"IPayCallback",CarrotPaySdkFinal.CMCC_PAY);
		} catch (Exception e) {
			// TODO: handle exception
			Log.e("cmcc_pay异常捕捉", "异常:"+e.toString());
		}
	}

5.重点就是上面 invokeContainsInterfaceStaticMethod 方法的实现

/**
	 * 执行包含接口的静态方法
	 * @param	className		类名
	 * @param	methodName		方法名
	 * @param	oArray			具体参数
	 * @param	paramTypeArray		构造参数类型
	 * @param	interfaceName	接口名
	 * @author liudb
	 * */
	public Object invokeContainsInterfaceStaticMethod(String className, String methodName,
			Object[] oArray,Class<?> [] paramTypeArray,String interfaceName,CarrotPaySdkFinal payType) throws Exception {
		Class<?> ownerClass = Class.forName(className);

		Class<?>[] argsClass = new Class[oArray.length];
		Method [] ms = ownerClass.getDeclaredMethods();
		for (int i = 0, j = oArray.length; i < j; i++) {
			argsClass[i] = oArray[i].getClass();
		}
		Method method = findMethod(ms, methodName, paramTypeArray, interfaceName);
		Class<?> clazz = Class.forName(othre_callBack.getName());
		//因为接口的最后一个参数是回调函数,所以要设置监测回调
		oArray[oArray.length -1] = Proxy.newProxyInstance(
	            clazz.getClassLoader(),
	            new Class[]{clazz},
	            new CarrotPayCallbackMethodInterceptor(payType));
		othre_callBack = null;
		return method.invoke(ownerClass, oArray);
	}

6.还有如何捕获回调的接口返回的参数 CarrotPayCallbackMethodInterceptor 类的实现

public class CarrotPayCallbackMethodInterceptor implements InvocationHandler {
	CarrotPaySdkFinal csf;
	public CarrotPayCallbackMethodInterceptor (CarrotPaySdkFinal paytype){
		csf = paytype;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		switch (csf) {
		case CMCC_PAY:
                //在这里获得回调函数返回的参数,通过自定义carrotSdkHelper发送给callback处理返回结果
                          for(int j = 0; j < args.length;j++){
				if(args[j].getClass().getName().equalsIgnoreCase("java.lang.Integer")){
					Integer result = (Integer)args[j];
					switch (result) {
					case 1:
						Message msg_cmcc_success = new Message();
						msg_cmcc_success.what = CarrotPaySDK.CARROT_PAY_SUCCESS;
						CarrotPaySDK.carrotSdkHleper.cmcc_PayendHandler.sendMessage(msg_cmcc_success);
						break;
					case 2:
						Message msg_cmcc_faild = new Message();
						msg_cmcc_faild.what = CarrotPaySDK.CARROT_PAY_FAILD;
						CarrotPaySDK.carrotSdkHleper.cmcc_PayendHandler.sendMessage(msg_cmcc_faild);
						break;
					default:
						Message msg_cmcc_faild2 = new Message();
						msg_cmcc_faild2.what = CarrotPaySDK.CARROT_PAY_FAILD;
						CarrotPaySDK.carrotSdkHleper.cmcc_PayendHandler.sendMessage(msg_cmcc_faild2);
						break;
					}
				}
			}
			break;
		case OTHER_PAY:
			Log.e("___________OTHER_______________", "____________________"+method.getName());
			
			for(int j = 0; j < args.length;j++){
				Log.e("___________OTHER_______________"+args[j].getClass().getName(), "____________________"+args[j].toString());
				
			}
			Log.e("___________OTHER_______________", "______333333______________");
			break;
		default:
			break;
		}
		
        return null;  
	}

}

7.(1)callback 类的介绍

public interface CarrotPayCallBack {  
	    public void onPayEnd(int isSuccess);  
	} 
(2)具体实现新建一个CarrotPayCallBack,传到4步骤的方法里

new CarrotPayCallBack() {
				
				@Override
				public void onPayEnd(int isSuccess) {
					// TODO Auto-generated method stub
					switch (isSuccess) {
					case CarrotPaySDK.CARROT_PAY_SUCCESS:
						Toast.makeText(getApplicationContext(), "支付成功", Toast.LENGTH_SHORT).show();
						break;
					case CarrotPaySDK.CARROT_PAY_CANCEL:
						Toast.makeText(getApplicationContext(), "支付取消", Toast.LENGTH_SHORT).show();
						break;
					case CarrotPaySDK.CARROT_PAY_FAILD:
						Toast.makeText(getApplicationContext(), "支付失败", Toast.LENGTH_SHORT).show();
						break;
					case CarrotPaySDK.CARROT_PAY_UNKNOW:
						Toast.makeText(getApplicationContext(), "未知错误", Toast.LENGTH_SHORT).show();
						break;
					default:
						break;
					}
				}
			}

8.代码已经提交到github,如有需要请移驾 点击打开链接

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值