1. 程式人生 > >java 反射呼叫帶回調介面的函式

java 反射呼叫帶回調介面的函式

        在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,如有需要請移駕點選開啟連結

相關推薦

java 反射呼叫帶回調介面函式

        在android開發中會遇到各種SDK的接入,很是麻煩。最初在想能不能把所有的SDK都融合到一個當中,發現有點異想天開。但是也可以解決SDK資源不小心沒有引入,導致程式呼叫介面崩潰問題。經過查資料,還是寫了一個小Demo,僅供參考!很早之前寫的了,估計移動基

利用JAVA反射機制實現調用私有方法

parse try ble cat 權限 利用 enabled tde mod 1.fragment是AccessibilityFragment的對象。須要被調用的方法的類。 setAccessible(true)並非將方法的訪問權限改成了public。而是取

java反射的工具類的函式集合

import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifi

使用java反射機制動態調用javabean的get,set方法

pre 完成 cep doc return 形參 語言 基本 實例 轉自:https://blog.csdn.net/lixinyao5281/article/details/70146177?locationNum=14&fps=1&t=149327688

java 反射呼叫Service導致Spring注入Dao失效

反射簡介    反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;    對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及    動態呼叫物件的方法的功能稱為java語言的反射機制。

Java非同步呼叫以及回撥函式

非同步呼叫 在網上看了半天文章,現在對非同步呼叫的理解就是在一個程序執行的過程中,有一個執行很長時間的方法,這時候可以建立一個執行緒去非同步呼叫這個方法,然後在方法執行完成之後呼叫回撥函式告訴主程序他執行完了。 就比如說使用者在點選列表展示的時候,如果資料庫效率很慢我們不能讓瀏覽器一直處

Java 反射呼叫類的屬性和方法(包含父類私有屬性和覆蓋重寫的方法等)

前面介紹了,反射呼叫類的構造方法來建立類的例項物件。一個類的結構包含方法(構造,靜態,非靜態)和屬性(靜態和非靜態)。按照迴圈漸進的方式,接下來,介紹反射類中屬性和普通的方法。 在這裡簡單介紹,反射呼叫屬性和方法會用到的新類,Method類和Field類。

java程式碼呼叫名片識別介面示例程式碼

介面名稱:名片識別 呼叫語言:java 文件引數: 請求引數: 名稱 型別 必填 說明 image string 是 名片影象的base64串 lang

使用java反射操作類的建構函式,成員變數和成員方法

在java.lang.reflect包中有三個類Field,Method,Constructor.分別描述域,方法,構造器。參考API,關於這三個類的說明。 在執行時使用反射分析物件,如果訪問的是私有域或是私有方法,私有建構函式,會丟擲IllegalAccessExce

根據物件中欄位屬性值,動態java反射呼叫相應的get方法

根據物件中欄位屬性值,動態呼叫相應的get方法 #### 舉個例子,把物件GoodsVO中的欄位作為key, get方法作為value,全部存放在Map中. //商品物件 public class GoodsVO { /** * 品牌ID */

Java 反射呼叫方法的引數是陣列的寫法

package com.heatdeath.fight.sort; import java.lang.reflect.Method; import java.util.Arrays; import j

java 反射 畫Sin、Cos函式曲線

package test; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;

java反射呼叫Bean指定方法

步驟:    一:獲取到bean的物件,方式有兩種,        1.通過Spring上下文獲取到bean物件Object object = SpringContextUtils.getBean(tableName+"Service"); Class sel

java jna呼叫迅雷介面下載

---> 不支援多執行緒 ---> 依賴32位jdk,windows 和jna.jar ---> 依賴 XLDownload.dll, zlib1.dll  放置專案跟目錄。不是src下,可以為絕對路徑 package com.leunpha; imp

JAVA反射呼叫詳解

JAVA反射呼叫的確是一種很神奇的機制,在專案中使用後戀戀不忘,現將其好好整理一下。 反射機制概述 反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。 這種動態獲取

Java 反射呼叫的一種優化

      寫一些Java框架的時候,經常需要通過反射get或者set某個bean的field,比較普通的做法是獲取field後呼叫java.lang.reflect.Field.get(Object),但每次都這樣呼叫,能否有優化的空間呢? 答案是有。 第一種:     

java反射中Parameter的getName函式如何得到引數名

如果jdk是1.8一下或者沒有設定帶引數名編譯,那麼Parameter的getName函式只會返回arg0,arg1,arg2......想要得到真正的引數名,得勾選一下帶引數名編譯的設定:這樣就ok了為什麼要勾選帶引數編譯的設定呢?想到前幾天學的詞法分析和語法分析才知道,變

Android:利用Java反射呼叫@hide的API

設定使用3G資料功能: 從原始碼看到隱藏的API(ConnectivityManager.java): /** * Sets the persisted value for enabling/disabling Mobile data. *

JAVA如何呼叫對方http介面得到返回資料

http://www.anjismart.com:7770/QueryCodeService.asmx/QueryCode?code=425144174493800&aid=302 瀏覽器訪問該連結的資料: <?xml version="1.0" encodi

java反射呼叫指定jar包中的類和方法

需求:動態載入jar包,例項化jar包中的類,並呼叫類中的方法 已知:jar包所在路徑和jar包名稱,類名已知,類繼承的抽象類可以被引入,類中的方法已知 實現方法: 1. 手動呼叫類載入器動態載入jar包; 2. 應用java中的反射例項化類,得到類的一個例項; 3. 運