APK自动生成的Lua脚本

        由于项目需要,需要脱离IDE来生成APK包,一开始我太天真,用纯bat去实现了一版,参见:http://www.oschina.net/code/snippet_170948_37095 ,但是bat的语法实在可怕,为了扩展的需要我又用Lua实现了一版,请戳:http://www.oschina.net/code/snippet_170948_38321 。

        下面就说下基本步骤和一些值得注意的小坑:

        一般来说,Android APK包的生成,利用IDE(Eclipse 或者 Android Studio)会比较方便,例如在Eclipse中可以将项目导出成签名或者非签名的APK包。想要实现自动化打包,就必须脱离IDE,自己去实现相关的步骤,不过幸好有一些自动化构建工具可以减轻我们的工作。

        通常来说java的一些项目构建工具,都可以用来构建APK包,例如ANT,MAVEN。ANT相对来说简单一些,我们选择的就是它。如下图,一个典型的APK包,包括assets,lib,META-INF,res,AndroidManifest.xml,class.dex等文件,其中assets是资源文件夹和res的区别是,res是无层次概念的,res中一般保存的是多媒体资源,assets一般保存lua,ccbi等文件。lib是编译后的jni库,就是.so文件。META是和签名相关的文件夹,用来MD5校验等。class.dex是经过编译后的java字节码文件,所有的java文件都将编译成一个字节码文件。

APK自动生成的Lua脚本

        APK自动化打包脚本就是分别生成以上文件夹,并生成zip包的过程。

        有一处需要说明的是,构建so文件,可以用cygwin,也可以使用NDK,NDK版本8以上是可以独立编译出so文件的。cygwin环境配置太复杂,所以直接选用NDK即可,NDK是区分32位和64位,需要注意NDK不同位宽并不兼容。

        使用Eclipse构建APK包的时候,需要将cocos2dx引擎下cocos2dx\platform\android\java\src目录中的org的源文件,拷贝到proj.android下的src文件中,使用脚本构建APK包的时候是通过mk文件指定库目录的,所以无需拷贝,否则会报重复定义的错。


        首先,在proj.android文件夹下的Android.mk文件,先指定编译NDK所需的目录,在文件中添加如下两行:

$(call import-add-path, $(LOCAL_PATH)/../../../..)

$(call import-add-path, $(LOCAL_PATH)/../../../../cocos2dx/platform/third_party/android/prebuilt)


        其次,是生成assets文件夹,每一次重新构建APK时,先删除旧的assets文件夹,之后再用luajit对lua文件生成相应字节码文件,最后将lua字节码文件加密,不需要加密的文件,只需要做拷贝即可,需要注意的是我在lua中编写测试文件夹是否存在函数的时候,发现win7和xp略有不同,代码如下:

       os.execute(string.format('pushd "%s">nul 2>nul && popd', dir))

       在win7 下上面的函数式返回true(文件夹存在),nil(文件夹不存在),而在xp下,是返回1,0。

       同时,最好删除旧有的APK包,在bin目录下,名为xxxx-release.apk,理论上APK生成方式是覆盖的,新的覆盖旧的,不过有时候会有bug,新的包覆盖不了,所以最好删除旧的APK包。

       使用luajit的时候也需要注意,必须要在同目录下加上luajit所依赖的lua51.dll和jit文件夹,编写luajit函数的时候有两点需要注意:

       1,我是通过os.excute来执行luajit的,所以必须要指定luajit运行的环境目录,单纯的执行luajit.exe会报jit文件夹不存在,所以应该通过pushd popd来指定环境文件夹,代码如下:

        function jit_file(toolpath, from , to)

               check_mk_filepath(to)

               local cmd1 = "pushd "..toolpath

               local cmd2 =  toolpath.."\\luajit.exe -bg " .. from .. " " .. to

               local cmd3 = "popd"

               local cmd = cmd1.." & "..cmd2.." & "..cmd3

               local res = run_one_cmd(cmd)

         end

         必须要用“&”符号来将3条指令,连接成一条指令去运行,否则还是不行,因为lua中使用os.excute执行一条指令时,是相当于一个trunk来执行,每个trunk是独立的,拥有自己的函数环境。

        2。luajit 使用-bg指令编译lua文件,出错时可以定位具体行号。


       然后,是使用NDK编译so库的过程,需要在NDK编译的参数中使用module-path来指定NDK的路径,通过如下指令即可完成:

        ndk-build -C "D:\engine\projects\XXXX\proj.android"  "NDK_MODULE_PATH=D:\engine;D:\engine\cocos2dx\platform\third_party\android\prebuilt"


        之后,使用android sdk的tools下的android update去更新工程目录和引擎目录,命令:

        android update project -p "D:\engine\projects\XXXX\proj.android 

        会生成proguard-project.txt和build.xml文件,这两个文件无需任何改动,并修改project.properties 中的参数,需要注意的是,你的sdk的版本是多少,在project.properties中的#project target参数就需要设置成多少,否则会报 missing target的错。

         update指令会更新该文件中的库目录路径,如下:

         android.library.reference.1=../../../cocos2dx/platform/android/java

        同时需要,需要使用Android update去更新库目录中的project.properties文件,命令如下:

        android update lib-project -p cocos2dx/platform/android/java


        最后,是使用ANT去生成APK包,这一步其实是ANT调用Android sdk的工具AAPT去完成的,命令很简单如下:

        ant release 或者 ant debug,release是生成APK包,debug是生成不签名的APK包(去掉一些优化), 

        在ant.properties指定签名所需的密钥文件,格式如下:

        key.store=”密钥文件名“(最好同目录下)

        key.alias=”签名作者“

        key.store.password=”发布密钥“

        key.alias.password=”签名密钥“


        AAPT的作用如下图所示:

APK自动生成的Lua脚本

       在新的SDK中传统的APKbuilder也已经被AAPT取代了。

       打包成功后,可以在bin目录下找到生成的APK包。

 

常见错误

       1.如果运行ANT 出现如下错误:

       BUILD FAILED

       D:\android-sdk-windows\tools\ant\build.xml:653:The following error occurred while executing this line:

       D:\android-sdk-windows\tools\ant\build.xml:698:null returned: 1

       解决方法是清楚bin目录下的所有文件,如果是在eclipse里面clean一下当前项目即可

 

       2.假设你将环境拷贝到别的机器上,使用别的机器进行NDK编译时,务必先删除obj目录,其中有大量缓冲文件,会导致路径未定义的错误。

 

       3.如果ANT出现如下错误

        D:\android-sdk-windows\tools\ant\build.xml: 950 

        D:\android-sdk-windows\tools\ant\build.xml: 932

        这是由于你的资源文件中出现了中文命名的文件,AAPT是没有办法识别的, IOS是可以识别的,但是AAPT不行,所以最好不要使用中文命名任何文件或者文件夹。



你可能感兴趣的:(APK自动生成的Lua脚本)