美文网首页Android打包androidAndroid开发
安卓新一代多渠道打包工具Walle

安卓新一代多渠道打包工具Walle

作者: tse1y | 来源:发表于2017-03-29 13:45 被阅读4487次

    广而告之,打开支付宝首页搜索7273592,即可领红包,每天都可以领

    为什么要打多个渠道的包?

    大家都知道,android应用商店大大小小有几百个,作为一个有志向的app,就需要做到统计各个应用商店的下载量,不同渠道下的app使用时长、安装数量、使用用户数等等信息,这个时候就需要打多个渠道包。渠道包的原理大致就是往apk中写入不同的渠道信息,对这个问题有疑问的同学可以看看gradle官网或者看看这篇文章

    传统多渠道打包

    用android studio开发的同学都知道,传统的多渠道打包方法是通过gradle配置productFlavors,在配合grade的manifestPlaceholders插件,就可以实现task打多渠道包了,具体如下。

        //app目录下在build.gradle文件中添加如下代码
        productFlavors {
            yingyongbao {
                manifestPlaceholders = [CUSTOM_CHANNEL_VALUE: "yingyongbao"]
            }
            baidu {
                manifestPlaceholders = [CUSTOM_CHANNEL_VALUE: "baidu"]
            }
        }
    
        //在AndroidManifest.xml中添加如下代码 如果有使用友盟把CUSTOM_CHANNEL换成UMENG_CHANNEL即可
            <meta-data
                android:name="CUSTOM_CHANNEL"
                android:value="${CUSTOM_CHANNEL_VALUE}" />
    

    这个时候就可以用task要打包了,双击即可。或者直接在命令行输入

    ./gradlew assembleRelease//打包所有渠道
    ./gradlew assembleWandoujiaRelease//打包单个渠道 Wandoujia
    
    1490758426(1).jpg

    没出现渠道打包task的同学请点击左上角的刷新按钮。

    Walle多渠道打包

    这种方法是很简单省事,但是并不省时啊!通过这种方式打包,gradle每次都要从资源文件开始到生成apk重新走一遍,所以很耗时,每次打包一次要等十几分钟,如果渠道多的app估计要等上半小时以上。这时候我们就要想想有没有其他的打包方式了,刚好在推酷上看到了美团开源的Android Signature V2 Scheme 签名下的新一代渠道包打包神器Walle,跟gradle打包不一样,walle是在APK Signature Block区块添加自定义的渠道信息,具体如下。

    1490759814(1).jpg
    当然了,Walle并不是为了解决打包速度而产生的一个工具,美团研究walle的原因是因为在Android 7.0(Nougat)推出了新的应用签名方案APK Signature Scheme v2后,之前快速生成渠道包的方式(美团Android自动化之旅—生成渠道包)已经行不通了,具体可以看看Walle自己是怎么说的。

    Walle简单使用

    Gradle 插件使用方式

    //配置 build.gradle
    //在位于项目的根目录 build.gradle 文件中添加Walle Gradle插件的依赖, 如下:
    
    buildscript {
        dependencies {
            classpath 'com.meituan.android.walle:plugin:1.0.3'
        }
    }
    
    //并在当前App的 build.gradle 文件中apply这个插件,并添加上用于读取渠道号的AAR,
    
    apply plugin: 'walle'
    
    //如果不需要通过walle获取渠道号 则不需要加
    dependencies {compile 'com.meituan.android.walle:library:1.0.3'}
    
    Walle信息配置
    //在当前App的 build.gradle 中添加如下信息
    walle {
        // 指定渠道包的输出路径
        apkOutputFolder = new File("${project.buildDir}/outputs/channels");
        // 定制渠道包的APK的文件名称 ${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk
        apkFileNameFormat = '${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
        // 渠道配置文件
        channelFile = new File("${project.getProjectDir()}/channel")
    
    }
    

    配置项具体解释:
    apkOutputFolder:指定渠道包的输出路径, 默认值为new File("${project.buildDir}/outputs/apk")

    apkFileNameFormat:定制渠道包的APK的文件名称, 默认值为'${appName}-${buildType}-${channel}.apk'
    可使用以下变量:

    projectName - 项目名字 
    appName - App模块名字
    packageName - applicationId (App包名packageName) 
    buildType - buildType (release/debug等) 
    channel - channel名称 (对应渠道打包中的渠道名字) 
    versionName - versionName (显示用的版本号) 
    versionCode - versionCode (内部版本号) 
    buildTime - buildTime (编译构建日期时间) 
    fileSHA1 - fileSHA1 (最终APK文件的SHA1哈希值) 
    flavorName - 编译构建 productFlavors 名
    

    channelFile:包含渠道配置信息的文件路径,channel文件放在module的同级目录下。 具体内容格式详见:渠道配置文件示例,支持使用#号添加注释。

    获取渠道

    在需要获取渠道信息的地方使用如下代码获取渠道信息

    String channel = WalleChannelReader.getChannel(this.getApplicationContext());
    

    通过读取<meta-data>来获取渠道号

        private void readMetaDataFromApplication() {  
            try {  
                ApplicationInfo appInfo = this.getPackageManager()  
                        .getApplicationInfo(getPackageName(),  
                                PackageManager.GET_META_DATA);  
                String mTag = appInfo.metaData.getString("mTag");  
      
                Log.e(TAG, "mTag=" + mTag);  
      
            } catch (NameNotFoundException e) {  
                e.printStackTrace();  
            }  
        }  
    
    打包

    生成渠道包的方式是和assemble${variantName}Channels指令结合,渠道包的生成目录默认存放在 build/outputs/apk/,也可以通过walle闭包中的apkOutputFolder参数来指定输出目录

    用法示例:

    • 生成渠道包
    mac ./gradlew clean assembleReleaseChannels
    win  gradlew clean assembleReleaseChannels
    
    • 支持 productFlavors
    mac ./gradlew clean assembleMeituanReleaseChannels
    win  gradlew clean assembleMeituanReleaseChannels
    
    • 生成单个渠道包
    mac ./gradlew clean assembleReleaseChannels -PchannelList=google
    win   gradlew clean assembleReleaseChannels -PchannelList=google
    
    • 生成多个渠道包
    mac ./gradlew clean assembleReleaseChannels -PchannelList=google,dianping
    win  gradlew clean assembleReleaseChannels -PchannelList=google,dianping
    
    更多用法

    github

    相关文章

      网友评论

      • 愤怒的五百万:请教一下,walle 不同渠道不同的app名,在productFlavors是怎么配置,能有个具体的代码吗,还是说在walle的configFile中配置。求解
        愤怒的五百万:@tse1y 明白了,多谢。我以为是一次性打不同的app名。
        tse1y:打个比方
        productFlavors {

        /** 360 **/
        qihoo {
        resValue "string", "app_name", "360渠道应用名"
        }
        }
        然后在AndroidManifest中这样写
        <application
        android:name="xxx"
        android:icon="xxx"
        android:label="@string/app_name">
        这样就能通过productFlovors配置app名,在通过
        gradlew clean assembleQihooReleaseChannels 打渠道包
        这种方式没办法一次性打不同app名,但是可以通过配置信息,快速打包
      • 3e6043b91737:Task 'assembleReleaseChannels' not found in root project 'TimeFinance'. Some candidates are: 'assembleAliReleaseChannels'. 出现这个错误
        tse1y:集成有问题,仔细看看配置信息有没有写错或者写错地方
      • 3e6043b91737:productFlavors {
        jinritoutiao {
        dimension "channel"
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "001jrtt"]
        // 动态修改 常量 字段
        buildConfigField "String", "ENVIRONMENT", '"今日头条"'
        }

        xiaomi {
        dimension "channel"
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "002xm"]
        buildConfigField "String", "ENVIRONMENT", '"小米"'
        }
        vivo {
        dimension "channel"
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "011vivo", app_icon: "@mipmap/dr_logo"]
        buildConfigField "String", "ENVIRONMENT", '"vivo"'
        }
        }

        楼主 像这种自己定义一个buildeConfig的静态成员变量 和 自己定义icon的资源walle怎么做
        3e6043b91737:@tse1y 好的谢谢
        tse1y:如果想配置除渠道外的信息,可以添加额外信息配置文件,但是icon资源,或者app名称这些没办法通过walle配置,walle的实现方式是在打完apk包后往包文件里面写入文件,而app图标、app名称这些是在打包的时候就要设置好的,你可以通过flavor加walle的方式去实现,但打包会慢一点
        walle {
        // 渠道&额外信息配置文件,与channelFile互斥
        configFile = new File("${project.getProjectDir()}/config.json")
        }
      • 繁体字遇上简体字:请问我使用了walle打包了,但是友盟那边怎么来获取到我的渠道包tag,谢谢
        tse1y:朋友,友盟sdk有设置渠道号的方法
        繁体字遇上简体字:我的意思是我获取渠道号码了,友盟那边怎么知道,附上代码
        val channelInfo = WalleChannelReader.getChannelInfo(this.getApplicationContext());
        if (channelInfo != null) {
        // tv.setText(channelInfo.getChannel() + "\n" + channelInfo.getExtraInfo());
        Log.e("ssssssssssssssssss", channelInfo.getChannel() + "\n" + channelInfo.getExtraInfo());
        }
      • _ljp:> Configure project :app
        useNewCruncher has been deprecated. It will be removed in a future version of the gradle plugin. New cruncher is now always enabled.
        The setTestClassesDir(File) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use the setTestClassesDirs(FileCollection) method instead.
        The getTestClassesDir() method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use the getTestClassesDirs() method instead.
        The ConfigurableReport.setDestination(Object) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use the method ConfigurableReport.setDestination(File) instead.
        The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.

        FAILURE: Build failed with an exception.

        * What went wrong:
        Task 'assembleReleaseChannels' not found in root project 'SuperMulti'.

        * Try:
        Run gradlew tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

        * Get more help at https://help.gradle.org

        BUILD FAILED in 2s

        请问楼主 这个问题有遇到过吗
        JackiePark:这个问题我也遇到了,请问楼主解决了吗
        _ljp:@tse1y 正常打包 不会唉
        tse1y:@刘军鹏 你试试正常打release包有没有问题
      • pioneerz:那种最简单的方式是怎么获取渠道号的?
        tse1y:你可以了解一下meta-data的使用
      • 木子木目:我在apply plugin: 'walle'时,报这个错
        Error:Plugin requires 'APK Signature Scheme v2 Enabled' for release.
        是什么原因,网上也没找到有这种错
        tse1y:方便贴一下你的代码吗
        木子木目:@tse1y 设置了
        tse1y:build.gradle中的buildTypes 有配置signingConfig 吗

      本文标题:安卓新一代多渠道打包工具Walle

      本文链接:https://www.haomeiwen.com/subject/zfkeottx.html