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

论坛 期权论坛 脚本     
匿名技术用户   2020-12-22 14:30   11   0

在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,如有需要请移驾点击打开链接

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP