APK自动打包

用Android Studio打包,每次等待软件启动都需要点时间。就想尝试能否进行自动打包,减少些不必要的时间。

一、.bat打包

批处理打包方式,要求Android Studio已经能够对工程进行打包。该方式实际上是使用命令替代在Android Studio中进行的打包按钮操作。
APK自动打包_第1张图片
结合cocos2dx的demo,使用了.properties文件,进行配置加密key,sign,是否加密,打包路径等,每次打某个路径下的资源,只需要配置 PROP_PROJECT_DIR 即可。

二、网页打包

使用 jenkins 进行自动化构建apk,在官网 【Jenkins官网】 下载window版本,选择默认安装即可。

安装后在浏览器输入 http://localhost:8080 ,通过admin 和 jenkins安装目录下secrets\initialAdminPassword下的密码进行登录

APK自动打包_第2张图片
创建新任务,输入任务名称,选择Freestyle Project,然后配置工程。

【源码管理】
APK自动打包_第3张图片
Repository URL : 项目路径

Credentials:访问项目的凭证

Local module directory:从URL拉取后放置的本地目录,相对于 Jenkins安装目录\workspace

本来想用本地仓库测试下就行,类似:file:///C:/Users/86158/Desktop/aaaa 但是这种仓库没有访问限制,Credentials 中无法设置,选择 也不能够访问该仓库,修改仓库下 conf/authz , conf/passwd, conf/svnserve,也无法访问。最后只能安装VisualSVN SERVER,进行测试

【构建】

选择 Invoke Gradle Script

APK自动打包_第4张图片
Wrapper location:.表示使用项目下的wrapper,项目下需要有gralde,gradlew,gradlew.bat文件
APK自动打包_第5张图片
【构建后操作】(可选)

配置该操作是为了构建成功能够显示构建成功的apk在jenkins面板上。如果没配置该操作,可以在构建成功后在Local module directory 中该项目文件夹下查看
APK自动打包_第6张图片
已配置完成,但还有几个点需要注意

  1. 确保能够在项目路径下使用gradlew clean assembleRelease进行打包

  2. 配置jenkins的 GRADLE_USER_HOME 环境变量,如果没有配置该变量,构建时会去下载。我的总是卡在下载处。

    APK自动打包_第7张图片

    配置路径 【Manage Jenkins 】->【Configure System】->【全局属性】->【Environment variables】

    APK自动打包_第8张图片

  3. 我的项目中用到了cocos命令,需要配置环境变量。这个命令不止需要cocos的,也需要python的。

    APK自动打包_第9张图片

    注意该键是path

【构建项目】

点击【Build Now】,构建完就能够在面板上看到apk

APK自动打包_第10张图片

https://blog.csdn.net/qq_24373725/article/details/80499054

三、多渠道打包

v1签名打包方式

  • 使用apktool.jar

    apktool能将apk解包,然后修改渠道号,在进行打包,最后使用jarsigner进行签名.

    【解包】

    APK自动打包_第11张图片

    【修改渠道号】

    APK自动打包_第12张图片

    【打包】

    java -jar apktool.jar b Game66_Test-release-360cn

    Game66_Test-release-360cn 下的dist目录下会输出打包后的apk

    【签名】

    在打包的路径下放置jks,使用jarsigner进行签名

    APK自动打包_第13张图片

    上面的流程可以打某个渠道包,对于多个渠道包,需要编写脚本进行自动化打包

    • 所有渠道号写在一个文件中
    • 签名文件放在apktool.jar同路径下
    • python读取渠道号,调用apktool解包,渠道号写入解包后的渠道文件内
    • python中调用apktool打包,python调用jarsigner签名
    #!/usr/bin/python
    # coding=utf-8
    import os
    import shutil
    
    def readChannelfile(filename):
        f = file(filename)
        while True:
            line = f.readline().strip('\n')
            if len(line) == 0:
                break
            else:
                channelList.append(line);
        f.close()
    
    def modifyChannel(value):
        output = open('./temp/assets/Game66Channel.txt', 'w')
        output.write(value)
        output.close()
    
        unsignApk = r'./bin/%s_%s_unsigned.apk'% (easyName, value)
        cmdPack = r'java -jar apktool.jar b temp -o %s'% (unsignApk)
        os.system(cmdPack)
        
        signedjar = r'./bin/%s-%s.apk'% (easyName, value)
        unsignedjar = r'./bin/%s_%s_unsigned.apk'% (easyName, value)
        cmd_sign = r'jarsigner -verbose -digestalg SHA1 -sigalg MD5withRSA -keystore %s -storepass %s -keypass %s -signedjar %s %s %s'% (keystore, storepass, keypass, signedjar, unsignedjar, alianame)
        os.system(cmd_sign)
        os.remove(unsignedjar);
        
    channelList = []
    #
    apkName = 'game66.apk'
    easyName = apkName.split('.apk')[0]
    keystore='./keystore/ace.jks'
    storepass='xxx'
    alianame='xxx'
    keypass='xxx'
    
    output_apk_dir="./bin"
    if os.path.exists(output_apk_dir):
        shutil.rmtree(output_apk_dir)
    
    readChannelfile('./channel')
    print '-------------------- your channel values --------------------'
    print 'channel list: ', channelList
    cmdExtract = r'java -jar apktool.jar  d -f -s %s -o temp'% (apkName)
    os.system(cmdExtract)
    print '--------is ok------------'
    
    for channel in channelList:
        print 'channel :',channel
        modifyChannel(channel)
    
    #if os.path.exists('./temp'):
        #shutil.rmtree('./temp')
    print '-------------------- Done --------------------'
    
    
    
  • META-INF写入渠道号

    使用apktool解包,在META-INF中写入渠道文件,apktool打包

  • APK中任意位置写入 空文件夹

    摘要+签名只是针对文件

  • End of Central Directory 写入注释

    https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.2.0.txt

    修改 End of Central Directory 最后部分的 注释以及注释长度 即可。

    腾讯的多渠道打包正是利用此方式。腾讯多渠道打包

V1签名不保护APK的某些部分,往META-INF下写入文件,无需重新签名

【V1签名的“Janus”漏洞】

https://cert.360.cn/warning/detail?id=d5a609929388cfd84c7e9aa8fb943265

V2签名打包方式

v2方案会将APK文件视为 Blob,并对整个文件进行签名检查。对APK进行的任何修改(包括对ZIP元数据进行的 修改)都会使 APK 签名作废。

  • 使用apktool.jar方式

    因为是重新签名,所以支持V1,V2打包方式

  • 美团walle

    原理:在APK签名块中添加一个ID-Value,存储渠道信息

    https://github.com/Meituan-Dianping/walle

  • 腾讯VasDolly

    原理:在APK签名块中添加一个ID-Value,存储渠道信息

    https://github.com/Tencent/VasDolly

VasDolly,支持V1,V2,且速度快,安全,相对较优

四、OpenInstall动态渠道

原理:

1、用户打开分享链接时,给当前手机生成一个唯一id,并发送给服务器。

2、用户下载app后,打开app,用1中同样的策略生成一个同样的id,发送给服务器。

这样就能将打开app的用户和下载链接对应起来;由于链接后面跟了渠道参数,然后就能将渠道和打开的用户对应起来。

这个原理不知是在哪里看到的,然后通过Fiddler抓包,发现每次打开链接,则会有发送给OpenInstall的请求,每次打开手机APP,同样也有OpenInstall的请求,两则缺一不可,虽然一遇到抓包,动态渠道就失效(应该是有防抓包机制),无法查看发送内容,但是原理与上面的描述一致。所以OpenInstall的动态渠道估计是这样的了。

你可能感兴趣的:(工具)