使用 Creator 打包的安卓原生應用中,我們可以通過反射機制直接在 JavaScript 中調用 Java 的靜態方法。它的使用方法很簡單:
var o = jsb.reflection.callStaticMethod(className, methodName, methodSignature, parameters...)
在 callStaticMethod 方法中,我們通過傳入 Java 的類名,方法名,方法簽名,參數就可以直接調用 Java 的靜態方法,並且可以獲得 Java 方法的返回值。下面介紹的類名和方法簽名可能會有一點奇怪,但是 Java 的規范就是如此的。
類名
參數中的類名必須是包含 Java 包路徑的完整類名,例如我們在 org.cocos2dx.javascript 這個包下面寫了一個 Test 類:
package org.cocos2dx.javascript;
public class Test {
public static void hello(String msg){
System.out.println(msg);
}
public static int sum(int a, int b){
return a + b;
}
public static int sum(int a){
return a + 2;
}
}
那么這個 Test 類的完整類名應該是 org/cocos2dx/javascript/Test,注意這里必須是斜線 / ,而不是在Java代碼中我們習慣的點 .。
方法名
方法名很簡單,就是方法本來的名字,例如sum方法的名字就是 sum。
方法簽名
方法簽名稍微有一點復雜,最簡單的方法簽名是 ()V,它表示一個沒有參數沒有返回值的方法。其他一些例子:
- (I)V 表示參數為一個int,沒有返回值的方法
- (I)I 表示參數為一個int,返回值為int的方法
- (IF)Z 表示參數為一個int和一個float,返回值為boolean的方法
現在有一些理解了吧,括號內的符號表示參數類型,括號后面的符號表示返回值類型。因為 Java 是允許函數重載的,可以有多個方法名相同但是參數返回值不同的方法,方法簽名正是用來幫助區分這些相同名字的方法的。
目前 Cocos Creator 中支持的 Java 類型簽名有下面 4 種:
|
Java類型
|
簽名
|
|
int
|
I
|
|
float
|
F
|
|
boolean
|
Z
|
|
String
|
Ljava/lang/String;
|
參數
參數可以是 0 個或任意多個,直接使用 JS 中的 number,bool 和 string 就可以。
使用示例
我們將會調用上面的Test類中的靜態方法:
// 調用hello方法
jsb.reflection.callStaticMethod("org/cocos2dx/javascript/Test", "hello", "(Ljava/lang/String;)V", "this is a message from js");
// 調用第一個sum方法
var result = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/Test", "sum", "(II)I", 3, 7);
cc.log(result); //10
// 調用第二個sum方法
var result = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/Test", "sum", "(I)I", 3);
cc.log(result); //5
在你的控制台會有正確的輸出的,這很簡單吧。
注意
另外有一點需要注意的就是,在 Android 應用中,cocos 引擎的渲染和 JS 的邏輯是在 GL 線程中進行的,而 Android 本身的 UI 更新是在 App 的 UI 線程進行的,所以如果我們在 JS 中調用的 Java 方法有任何刷新 UI 的操作,都需要在 UI 線程進行。
例如,在下面的例子中我們會調用一個Java方法,它彈出一個 Android 的 Alert 對話框。
// 給我們熟悉的 AppActivity 類稍微加點東西
public class AppActivity extends Cocos2dxActivity {
private static AppActivity app = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = this;
}
public static void showAlertDialog(final String title,final String message) {
// 這里一定要使用 runOnUiThread
app.runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog alertDialog = new AlertDialog.Builder(app).create();
alertDialog.setTitle(title);
alertDialog.setMessage(message);
alertDialog.setIcon(R.drawable.icon);
alertDialog.show();
}
});
}
}
然后我們在 JS 中調用
jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "showAlertDialog", "(Ljava/lang/String;Ljava/lang/String;)V", "title", "hahahahha");
這樣調用你就可以看到一個 Android 原生的 Alert 對話框了。
