安卓SDK接入so easy,一文看懂Cocos Creator原生二次開發(fā)的正確姿勢!
引言:本文作者「羽毛先生」,他將基于 v3.4.2,介紹 Cocos Creator 的 Android 原生二次開發(fā)流程以及 JSB 進行 Android 層與引擎 TS/JS 層進行相互調用的過程。Demo 源碼見文末。
最近在開發(fā)的一個游戲進入到了安卓 SDK 接入的相關工作,但是構建安卓工程后,發(fā)現結構跟以往的 jsb-link 差別比較大,項目目錄結構和以前也有所不同。本次就聊一聊 Cocos Creator 的安卓原生二次開發(fā),為開發(fā)的小伙伴提供一些參考。
分析過程
首先查閱一下官方文檔中對構建目錄[1]、二次開發(fā)[2]的說明。


構建目錄

二次開發(fā)

注意事項
接著查看本地文件。
/build/android/proj 目錄:
查看
/build/android/proj未發(fā)現AppActitivy.java等文件,但是存在build.gradle等安卓相關文件。使用Android Studio 打開目錄,可以成功打開并編譯。
native 目錄:
查看
/native/engine/android/app目錄,存在AndroidMainfest.xml,build.gradle等文件。

查看
/native/engine/android/app/com/cocos/game,可以看到有AppActitivy.java發(fā)現以上是熟悉的安卓工程目錄結構。使用 Android Studio 打開目錄,報錯。
跟隨文檔,使用 Android Studio 打開 build/android/proj,發(fā)現找不到上述的 AndroidMainfest.xml,build.gradle,以及 /native/engine/android/app/com/cocos/game/Appactivity,這時候只要切換一下顯示模式為 Android 即可。

切換后即可看到相關的原生文件。

通過 Android Studio 中使用 Windows 資源管理器打開 AppActivty.java 可以發(fā)現 AppActivity.java 位于 native/engine/android/app/src/com/cocos/game 目錄中。


總結:在 build/android/proj 使用 Android Studio 進行開發(fā),生效文件位于 native/engine/android 中,對 native 目錄做版本管理,同時需去除 native 下的 build 目錄(編譯過程臨時生成內容)。
build/android 目錄中為 Cocos Creator 配置的 service 內容,隨工程改變,不需要做單獨的版本管理。
接入流程示例
接下來以 TalkingData SDK 為例,介紹一下完整的安卓原生工程二次開發(fā)流程。下載好 SDK 后打開 SDK 文檔,參照文檔指引進行接入。
TalkingData SDK 接入文檔
https://doc.talkingdata.com/posts/1025
首先在編輯器中進行安卓原生構建。構建的相關選項請參考官方文檔[3],文檔有很詳細的說明。

構建完成后,可在工程目錄下看到 native、build/android 兩個目錄。


接著使用 Android Studio 打開 build/android/proj 并且切換到 Android 顯示模式。

然后我們來根據 SDK 接入文檔進行接入。
? 1、導入 SDK。

在 native/engine/android/app/ 目錄下新建 libs 目錄(可在 Android Studio 中通過 show in explore 使用 Windows 資源管理器打開,自動跳轉到該目錄)。

在 \native\engine\android\app 下創(chuàng)建 libs 目錄,復制 SDK 中的 aar 等文件到 libs 下,并在 app module 所屬的 build.gradle 中添加依賴。

此處需要注意 libs 目錄的中的 aar/jar 文件并非 talkingdata 接入文檔中的 TalkingdataSDK.jar,而是 SaaS_TalkingDataSDK_Android_V5.0.3.jar(下載 SDK 時提供的文件名),在接入其他的 SDK 中也常常會有這樣的細節(jié)問題,需要注意以免被坑。
? 2、配置混淆規(guī)則。

打開 app module 所屬 proguard-rules.pro 添加混淆規(guī)則。

? 3、如上同理按照文檔要求進行權限配置。

? 4、SDK 初始化、接口實現等,內容相似,則不贅述了。這里展示關鍵性的代碼,詳細內容見 Demo 源碼。

TDSDK.java:
package com.cocos.sdk;
import android.util.Log;
import com.cocos.game.AppActivity;
import com.cocos.lib.CocosHelper;
import com.cocos.lib.CocosJavascriptJavaBridge;
import com.tendcloud.tenddata.TalkingDataProfile;
import com.tendcloud.tenddata.TalkingDataProfileType;
import com.tendcloud.tenddata.TalkingDataSDK;
public class TDSDK {
static String AppID = "xxxxxxxxx";
static String Chanel = "test_channel";
static TDSDK s_self = null;
public static TDSDK getInstance(){
if (s_self == null){
s_self = new TDSDK();
}
return s_self;
}
public void init(){
TalkingDataSDK.init(AppActivity.getContext(),AppID,Chanel, "");
}
public static void onResgister(String accountId){
if (accountId==""){
accountId = TalkingDataSDK.getDeviceId(AppActivity.getContext());
}
TalkingDataProfile profile = TalkingDataProfile.createProfile();
profile.setName("");
profile.setType(TalkingDataProfileType.ANONYMOUS);
TalkingDataSDK.onRegister(accountId, profile,"");
}
public static String js2JavaTest(String str1, String str2){
Log.d("TDSDK", String.format( "js2JavaTest Success param1:%s param2: %s",str1, str2));
if (s_self!= null) s_self.java2js();
return "Java Test Success";
}
public void java2js(){
CocosHelper.runOnGameThread (new Runnable() {
@Override
public void run() {
String str1 = "param3";
String str2 = "param4";
String funcStr = String.format("window.tdsdk.java2js('%s','%s')",str1,str2);
Log.d("-----------------------", "Start Java2Js");
CocosJavascriptJavaBridge.evalString(funcStr);
Log.d("----------------------", "End Java2Js");
}
});
}
}
Appactivity.java,建議可以簡單了解下 Android 各個生命周期函數執(zhí)行時機以及機制:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DO OTHER INITIALIZATION BELOW
SDKWrapper.shared().init(this);
TDSDK.getInstance().init();
}
? 5、接入完成后可以直接在 Android Studio 中進行打包。apk 生成路徑:android-001\proj\build\sdkDemo\outputs\apk
android-001 為在 Creator 構建界面的構架任務名。

也可以在 Cocos Creator 構建工具中點擊生成進行打包。apk 生成路徑:\build\android-001\publish android-001 為在 Creator 構建界面的構架任務名。
如果進行了 JS 層代碼修改,則還需要通過編輯器的構建流程進行工程構建,然后再進行生成,使代碼生效。
按照引擎設計,native 目錄生成后,再次構建將跳過這部分的生成,避免影響已經開發(fā)的 Android SDK、native C++ 等原生定制的內容,在此也建議將 native 目錄加入 git/svn 版本控制。
? 6、打包測試,運行成功,后臺可收到激活設備,大功告成?。?!

JS/TS與Android方法互調
Android 層接入完畢后,則需要實現 Java 與 TS 的互調。查閱官方文檔[4]可知:
TS 調用 Java:
jsb.reflection.callStaticMethodJava 調用 TS,使用
evalString,請注意觀察示例代碼中的 evalString 函數中參數的單引號雙引號使用,避免出錯。
示例:
Cocos Creator TS 代碼:
const classPath = "com/cocos/sdk/TDSDK";
@ccclass('tdsdk')
export class tdsdk {
private static _instance = null;
static getInstance(): tdsdk {
if (tdsdk._instance == null) {
tdsdk._instance = new tdsdk();
}
return tdsdk._instance;
}
//js調用Java
js2Java() {
if (JSB) {
log("********************start js2Java param1: title param2: content********************");
let res = jsb.reflection.callStaticMethod(classPath, "js2JavaTest", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", "title", "content");
log("返回值", res);
log("********************end js2Java param1: title param2: content********************");
}
}
//java調用js
java2js(param1: string, param2: string) {
if (!JSB) {
}
log("java2js success param3: %s param4:%s ", param1, param2);
}
}
window.tdsdk = tdsdk.getInstance();
請注意代碼末尾將 tdsdk 掛在 Window 上,并且在 Cocos Creator 根目錄創(chuàng)建 .d.ts 文件對 tdsdk 進行全局聲明(文件名隨意,不跟已有的沖突即可),方便別處調用時可以進行代碼提示。

global.d.ts:
import { tdsdk } from "./assets/script/tdsdk";
declare global {
interface Window {
tdsdk: tdsdk
}
}
Java 代碼:
public static String js2JavaTest(String str1, String str2){
Log.d("TDSDK", String.format( "js2JavaTest Success param1:%s param2: %s",str1, str2));
if (s_self!= null) s_self.java2js();
return "Java Test Success";
}
public void java2js(){
CocosHelper.runOnGameThread (new Runnable() {
@Override
public void run() {
String str1 = "param3";
String str2 = "param4";
String funcStr = String.format("window.tdsdk.java2js('%s','%s')",str1,str2);
Log.d("-----------------------", "Start Java2Js");
CocosJavascriptJavaBridge.evalString(funcStr);
Log.d("----------------------", "End Java2Js");
}
});
}
注意在 Java 調用 JS 代碼時,如果需要操作 UI,請在規(guī)定線程中調用(runOnGameThread),避免崩潰,這里建立規(guī)范統(tǒng)一在規(guī)定線程中調用。
運行結果:

更高級的互調方式,請參考「騰訊在線教育部技術博客」中的 JSB 自動綁定方案,主要介紹了 C++ 與 JS 的互調:
http://docs.cocos.com/creator/manual/zh/advanced-topics/jsb-auto-binding.html?h=jsb

資源下載
點擊文末【閱讀原文】下載 Demo 源碼
https://gitee.com/zenskcode/creatorDemo/tree/master/demos/AndroidSdkDemo-3.4.2
以上介紹完成了 SDK 接入以及 Java、TS 互調的相關用法,掌握后應該可以完成大部分安卓 SDK 的接入工作了,也可進行一些原生系統(tǒng)的調用。
參考鏈接
[1] 構建目錄-官方文檔
https://docs.cocos.com/creator/manual/zh/editor/publish/native-options.html?q=#%E6%9E%84%E5%BB%BA%E7%9B%AE%E5%BD%95
[2] 二次開發(fā)-官方文檔
https://docs.cocos.com/creator/manual/zh/editor/publish/native-options.html?q=#%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91
[3] 打包發(fā)布到原生平臺-官方文檔
http://docs.cocos.com/creator/manual/zh/editor/publish/native-options.html
[4] Java 反射-官方文檔
http://docs.cocos.com/creator/manual/zh/advanced-topics/java-reflection.html
本文轉載自公眾號「羽毛不會飛」,
歡迎關注作者!
往期精彩



