1. 程式人生 > >Cocos2d-x遊戲匯出android工程,提取cocos的so檔案

Cocos2d-x遊戲匯出android工程,提取cocos的so檔案

  Cocos2d-x遊戲匯出android工程,提取cocos的so檔案   原本cocos遊戲的android工程編譯時,需要將cocos的庫檔案進行編譯,這些檔案大部分是cpp檔案, 使用ndk-build工具編譯cpp檔案非常慢,而且非常耗cpu,大概需要10-20分鐘才能編譯完成,這個還是因為我換了固態硬碟後的效果,沒固態硬碟可能就gg   這個等待時間可能是一個不錯的水群時間,或者上去看看新聞,有哪個好看的,好玩的。 但事與願違啊! 電腦編譯這個工程已經佔據的80%cpu,這叫人怎麼辦啊,涼涼,只能慢慢等待,然而後面還有一大堆事情等著我們去處理,看來加班時間又得延長~ 。   眾裡尋它千百度,想的又想,都是一個cocos軟體匯出來的cocos庫,怎麼就不可以共用呢,覺得沒道理啊。唯一不同的應該就是js檔案吧 先來個正常匯出工程截圖 這是jsb-default資料夾內的檔案。js backups(useful for debugging)這個是js原始碼檔案,沒什麼用處   A .遊戲資源 jsb-adapter, res src main.js project.json 這五個檔案是不同遊戲的不同js檔案,有遊戲的js指令碼,res有遊戲圖片資源,main.js應該是遊戲的主入口,負責載入資源及指令碼   看完遊戲資源,再看下frameworksw資料夾  

一個是cocos2d-x庫檔案,還有一個runtime-src這裡放著各個平臺的工程檔案還有一個classes資料夾

B. 遊戲需要的Classes檔案

有三個平臺,android,mac,win

只看android工程檔案proj.android-studio

可以使用android studio開啟這個工程

 

開啟build.gradle檔案,

externalNativeBuild是用來配置生成so包的cpu架構

externalNativeBuild {
            ndkBuild {
                if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
                    
// skip the NDK Build step if PROP_NDK_MODE is none targets 'cocos2djs' arguments 'NDK_TOOLCHAIN_VERSION=4.9' def module_paths = [project.file("../../../cocos2d-x"), project.file("../../../cocos2d-x/cocos"), project.file(
"../../../cocos2d-x/external")] if (Os.isFamily(Os.FAMILY_WINDOWS)) { arguments 'NDK_MODULE_PATH=' + module_paths.join(";") } else { arguments 'NDK_MODULE_PATH=' + module_paths.join(':') } arguments '-j' + Runtime.runtime.availableProcessors() abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String}) } } } }

 

// Specifies which native libraries to build and package for this
          // product flavor. If you don't configure this property, Gradle
          // builds and packages all shared object libraries that you define
          // in your CMake or ndk-build project.
targets 'cocos2djs'

這個targets引數,指定哪個native庫用來構建和打包,如果沒有配置這個屬性,gradle會 將所有native庫進行構建和打包,

猜測應該是呼叫cocos2djs這個底層庫進行編譯

arguments是gradle配置ndk引數的方法,用來設定ndk-build打包時的引數

最重要的是abiFilters這個過濾,規定需要打包的CPU架構,

abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})

PROP_APP_ABI屬性是從Android工程的gradle.properties檔案中獲取到了

PROP_TARGET_SDK_VERSION=19
PROP_APP_ABI=armeabi-v7a:x86:arm64-v8a

 表示以:分割,

這樣編譯後會出來三個架構的so檔案

C,獲得so檔案

我們想要的so檔案就出來了,只要編譯出來的遊戲可以正常執行,我們就可以提取這個so檔案。

note:需要提取的是ndkBuild-》release->...->armeabi-v7a中的so檔案,上面截圖中的是調式的so

 

現在我們需要的資源都已經準備好的,可以進行工程的組合

,保險起見,我們新建一個資料夾進行android工程簡化。

比如一個籃球遊戲,新建basketball資料夾

將as工程所有檔案複製到basketball中,注意,紅框中的檔案不需要修改,

一. 修改app下的檔案,將上面標註的A js資原始檔放到assets目錄中

 

 

二. 將C中獲得的so檔案放到libs包對應cpu架構下面

還有需要將cocos依賴的jar包也放到lib下面

D:\android-workspace\frameworks\cocos2d-x\cocos\platform\android\java\libs

這四個jar包放到我們app的libs檔案下

三。 新增額外的java 的cocos庫檔案

 需要將libs原始碼檔案提取出來放到我們的app/src/main/java中

目錄路徑

D:\android-workspace\frameworks\cocos2d-x\cocos\platform\android\java\src\org\cocos2dx\lib

複製到src.main.java

 

 

 四. 修改app/build.gradle檔案

主要就是刪除掉打包編譯so檔案的程式碼,去掉無用的依賴庫

修改前

import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.application'

android {
    compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
    buildToolsVersion PROP_BUILD_TOOLS_VERSION

    defaultConfig {
        applicationId "com.uelink.JewelBlockPuzzle"
        minSdkVersion PROP_MIN_SDK_VERSION
        targetSdkVersion PROP_TARGET_SDK_VERSION
        versionCode 1
        versionName "1.0"

        externalNativeBuild {
            ndkBuild {
                if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
                    // skip the NDK Build step if PROP_NDK_MODE is none
                    targets 'cocos2djs'
                    arguments 'NDK_TOOLCHAIN_VERSION=4.9'

                    def module_paths = [project.file("../../../cocos2d-x"),
                                        project.file("../../../cocos2d-x/cocos"),
                                        project.file("../../../cocos2d-x/external")]
                    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                        arguments 'NDK_MODULE_PATH=' + module_paths.join(";")
                    }
                    else {
                        arguments 'NDK_MODULE_PATH=' + module_paths.join(':')
                    }
                    
                    arguments '-j' + Runtime.runtime.availableProcessors()
                    abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})
                }
            }
        }
    }

    sourceSets.main {
        java.srcDir "src"
        res.srcDir "res"
        jniLibs.srcDir "libs"
        manifest.srcFile "AndroidManifest.xml"
    }

    externalNativeBuild {
        ndkBuild {
            if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
                // skip the NDK Build step if PROP_NDK_MODE is none
                path "jni/Android.mk"
            }
        }
    }

    signingConfigs {

       release {
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                storeFile file(RELEASE_STORE_FILE)
                storePassword RELEASE_STORE_PASSWORD
                keyAlias RELEASE_KEY_ALIAS
                keyPassword RELEASE_KEY_PASSWORD
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                signingConfig signingConfigs.release
            }

            externalNativeBuild {
                ndkBuild {
                    arguments 'NDK_DEBUG=0'
                }
            }
        }

        debug {
            externalNativeBuild {
                ndkBuild {
                    arguments 'NDK_DEBUG=1'
                }
            }
        }
    }
}

android.applicationVariants.all { variant ->
    // delete previous files first
    delete "${buildDir}/intermediates/assets/${variant.dirName}"

    variant.mergeAssets.doLast {
        copy {
           from "${buildDir}/../../../../../res"
           into "${buildDir}/intermediates/assets/${variant.dirName}/res"
        }

        copy {
            from "${buildDir}/../../../../../src"
            into "${buildDir}/intermediates/assets/${variant.dirName}/src"
        }

        copy {
            from "${buildDir}/../../../../../jsb-adapter"
            into "${buildDir}/intermediates/assets/${variant.dirName}/jsb-adapter"
        }

        copy {
            from "${buildDir}/../../../../../main.js"
            from "${buildDir}/../../../../../project.json"
            into "${buildDir}/intermediates/assets/${variant.dirName}"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation fileTree(dir: "../../../cocos2d-x/cocos/platform/android/java/libs", include: ['*.jar'])
    implementation project(':libcocos2dx')
}

 

 修改後

import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.application'

android {
    compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
    buildToolsVersion PROP_BUILD_TOOLS_VERSION

    defaultConfig {
        applicationId "com.uelink.JewelBlockPuzzle"
        minSdkVersion PROP_MIN_SDK_VERSION
        targetSdkVersion PROP_TARGET_SDK_VERSION
        versionCode 1
        versionName "1.0"
    }

    sourceSets.main {
        java.srcDir "src"
        res.srcDir "res"
        jniLibs.srcDir "libs"
        manifest.srcFile "AndroidManifest.xml"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            externalNativeBuild {
                ndkBuild {
                    arguments 'NDK_DEBUG=0'
                }
            }
        }

        debug {
            externalNativeBuild {
                ndkBuild {
                    arguments 'NDK_DEBUG=1'
                }
            }
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

 

可能還需要修改下java檔案包名,修改寫報錯,程式就可以正常運行了。