打包工程支持导入Android Studio说明
一、目的
为了不破坏原有打包工程结构(Eclipse工程结构),但支持导入打包工程到Android Studio中。
二、导入步骤
-
整个工程中主应用为Game66_Test,当前依赖工程有Game66_common,Game66_self,COCOS2DXLIB,PaySdk1
-
在AS中,工程与模块概念与Eclipse不同。AS中可将整个上层文件夹Game66作为工程,其他可作为模块形式,所以在Game66下可 替换/新建 settings.gradle文件,导入必要模块
include ':Game66_Test',':libraries:Game66_common',':libraries:COCOS2DXLIB',":libraries:Game66_self",":libraries:PaySdk1"
-
删除Game66_Test,Game66_common,Game66_self,COCOS2DXLIB,PaySdk1下的iml文件,
-
为了最大程度少加文件,少改文件,可以不需要在Game66文件夹下新建build.gradle,直接修改原有每个模块下build.gradle下的gradle构建版本就行,可以在AS中查看gradle插件版本。修改Game66_Test,Game66_common,Game66_self,COCOS2DXLIB,PaySdk1下的build.gradle文件,其中compileSdkVersion和buildToolsVersion可根据自己AS中的版本适当调整,避免下载SDK。
以Game66_Test中的build.gradle为例:
buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.1.1' } } def versionName1 = "1.0.0.12"; def versionCode1 = 10000012; apply plugin: 'com.android.application' //表明是android项目 android { compileSdkVersion 22 buildToolsVersion '28.0.1' defaultConfig { versionCode versionCode1 versionName versionName1 } signingConfigs {//签名文件 debug { storeFile file('bailemen.jks') storePassword "game66@bailemen" keyAlias "bailemen" keyPassword "game66@bailemen" } } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } androidTest.setRoot('tests') } lintOptions { abortOnError false } } dependencies { implementation project(':libraries:Game66_self') }
其中主要修改的是gradle插件版本,去掉不必要的内容,原本setup()和android.applicationVariants.all好像没用到,不需要,如果想要这部分内容,因为gradle版本不一致,可能需要修改里面的部分代码,还有就是修改依赖。
其他几个build.gradle修改方式一样,区别在于依赖库。可以以下面代码为模板,修改依赖库。
buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.1.1' } } apply plugin: 'com.android.library' android { compileSdkVersion 22 buildToolsVersion '28.0.1' sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } androidTest.setRoot('tests') } } tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } dependencies { api project(':libraries:PaySdk1') api project(':libraries:Game66_common') }
-
Game66_common项目libs/armeabi下需要有libcocos2dxlua.so文件
-
按照上述步骤弄好后,打开AS,选择Open an existing Android Studio project,选择Game66下的setting.gradle,选择OK使用Gradle wrapper,完成。
三、加密扩展
现在的项目,每次打包都需要单独对代码进行加密,然后再将加密后的代码拉到asset中,步骤繁琐。可以从两个方面进行优化,提高打包效率。1,配置工程目录,每次打包时,自动从该目录下copy对应的res,src到assets目录下;2,打包时,需要将assets下的src中所有lua文件进行加密。
一、配置工程目录,打包时从该目录下copy对应的res,src到assets目录下
在Game66文件夹下新建gradle.properties
# replace your project dir
PROP_PROJECT_DIR=E:/Game66/bailemen
在Game66_Test下的build.gradle文件中修改,需要添加的部分代码如下
// copy project
if (project.hasProperty('PROP_PROJECT_DIR')) {
delete "${buildDir}/../assets/res"
delete "${buildDir}/../assets/src"
copy {
from project.property('PROP_PROJECT_DIR') + "/res"
into "${buildDir}/../assets/res"
}
copy {
from project.property('PROP_PROJECT_DIR') + "/src"
into "${buildDir}/../assets/src"
}
}
二,打包时进行加密
思路:将assets下的src拷贝到 "buildDir/intermediates/assets/{buildDir}/intermediates/assets/buildDir/intermediates/assets/{variant.dirName}/src"下,然后调用cocos 命令(需要本地配置cocos环境变量)进行加密。
在Game66_Test下的build.gradle文件中修改,加密部分关键代码如下
def getCocosCommandPath() {
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
return 'cocos.bat'
}
else {
// on unix like system, can not get environments variables easily
// so run a shell script to get environment variable sets by cocos2d-x setup.py
new ByteArrayOutputStream().withStream { os ->
def result = exec {
executable = project.file('get_environment.sh')
standardOutput = os
}
ext.console_path = os.toString().trim()
}
return new File(console_path + '/cocos').absolutePath;
}
}
整体流程如下:
1,本地配置cocos环境变量
2,在Game66文件夹下新建gradle.properties
PROP_LUA_ENCRYPT_KEY=2dxLua
PROP_LUA_ENCRYPT_SIGN=XXTEA
PROP_LUA_ENCRYPT=1
# replace your project dir
PROP_PROJECT_DIR=E:/Game66/bailemen
3,在Game66_Test文件夹下新建get_environment.sh(linux下支持cocos命令)
#!/bin/bash
source ~/.bash_profile
echo $COCOS_CONSOLE_ROOT
4,在Game66_Test文件夹下的build.gradle中增加如下代码
// a method used to invoke the cocos luacompile command
def compileLua(srcDir, dstDir, doCompile, is64bit, doEncrypt) {
def compileArgs = ['luacompile', '-s', srcDir, '-d', dstDir]
if (!doCompile) {
compileArgs << '--disable-compile'
}
else if (is64bit) {
compileArgs << '--bytecode-64bit'
}
if (doEncrypt) {
compileArgs << '-e'
compileArgs << '-k'
compileArgs << project.property('PROP_LUA_ENCRYPT_KEY')
compileArgs << '-b'
compileArgs << project.property('PROP_LUA_ENCRYPT_SIGN')
}
// commandLine compileArgs
println 'running command : ' + 'cocos ' + compileArgs.join(' ')
exec {
// if you meet problem, just replace `getCocosCommandPath()` to the path of cocos command
executable getCocosCommandPath()
args compileArgs
}
// remove the lua files in dstDir
delete fileTree(dstDir) {
include '**/*.lua'
}
}
def getCocosCommandPath() {
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
return 'cocos.bat'
}
else {
// on unix like system, can not get environments variables easily
// so run a shell script to get environment variable sets by cocos2d-x setup.py
new ByteArrayOutputStream().withStream { os ->
def result = exec {
executable = project.file('get_environment.sh')
standardOutput = os
}
ext.console_path = os.toString().trim()
}
return new File(console_path + '/cocos').absolutePath;
}
}
android.applicationVariants.all { variant ->
// delete previous files first
delete "${buildDir}/intermediates/assets/${variant.dirName}"
variant.mergeAssets.doLast {
// copy project
if (project.hasProperty('PROP_PROJECT_DIR')) {
delete "${buildDir}/../assets/res"
delete "${buildDir}/../assets/src"
copy {
from project.property('PROP_PROJECT_DIR') + "/res"
into "${buildDir}/../assets/res"
}
copy {
from project.property('PROP_PROJECT_DIR') + "/src"
into "${buildDir}/../assets/src"
}
}
copy {
from "${buildDir}/../assets/res"
into "${buildDir}/intermediates/assets/${variant.dirName}/res"
}
copy {
from "${buildDir}/../assets/src"
into "${buildDir}/intermediates/assets/${variant.dirName}/src"
}
// compile & encrypt the scripts if necessary
def compileScript = (variant.name.compareTo('release') == 0)
if (project.hasProperty('PROP_COMPILE_SCRIPT')) {
compileScript = (PROP_COMPILE_SCRIPT.compareTo('1') == 0)
}
def encryptLua = project.hasProperty('PROP_LUA_ENCRYPT') && (PROP_LUA_ENCRYPT.compareTo('1') == 0)
if (compileScript || encryptLua) {
// -1 means not build bytecode
// 0 means build 32bit only
// 1 means build 64bit only
// 2 means build both 32bit & 64bit
def buildType = -1
if (compileScript) {
def need64 = false
def need32 = false
def abis = PROP_APP_ABI.split(':').collect{it as String}
abis.each{ abi->
if (abi.compareTo('arm64-v8a') == 0) {
need64 = true
}
else
{
need32 = true
}
}
if (need64 && need32) {
buildType = 2
}
else if (need64) {
buildType = 1
}
else {
buildType = 0
}
}
// invoke cocos command to compile & encrypt the lua files
switch (buildType) {
case -1:
compileLua("${buildDir}/intermediates/assets/${variant.dirName}/src",
"${buildDir}/intermediates/assets/${variant.dirName}/src",
false, false, encryptLua)
break
case 0:
compileLua("${buildDir}/intermediates/assets/${variant.dirName}/src",
"${buildDir}/intermediates/assets/${variant.dirName}/src",
true, false, encryptLua)
break
case 1:
compileLua("${buildDir}/intermediates/assets/${variant.dirName}/src",
"${buildDir}/intermediates/assets/${variant.dirName}/src/64bit",
true, true, encryptLua)
// remove the lua files in src dir
delete fileTree("${buildDir}/intermediates/assets/${variant.dirName}/src") {
include '**/*.lua'
}
delete "${buildDir}/intermediates/assets/${variant.dirName}/src/cocos"
break
case 2:
compileLua("${buildDir}/intermediates/assets/${variant.dirName}/src",
"${buildDir}/intermediates/assets/${variant.dirName}/src/64bit",
true, true, encryptLua)
compileLua("${buildDir}/intermediates/assets/${variant.dirName}/src",
"${buildDir}/intermediates/assets/${variant.dirName}/src",
true, false, encryptLua)
break
}
}
}
}
5,在刚刚Game66下新建的gradle.properties中修改字段PROP_PROJECT_DIR
的值,指向自己的工程目录