Jb的测试之旅-安卓多渠道包

申明

本文没有说起到啥新技术,相反的,都是看几年前的技术,所以,本文不适合安卓开发同窗,对不了解的同窗会有必定的帮助;android

所以,请各位大牛勿喷,谢谢~ git

image.png-31.1kB

前言

(一脸幽怨)这个事,终究仍是落在jb身上了,事情通过是这样的:github

每次发版本,安卓都须要上传N个商店,而不一样的渠道须要打不一样的渠道标识,
当APP和后台交互或者数据上报时,会带上各自的渠道信息。这样就能统计
到每一个分发市场的下载数、用户数等关键数据;
复制代码

这块呢,原本是让产品实习生负责,结果呢,过完年后,实习生要回校了,产品老大不肯意作这事,测试只剩下一我的了,顺其而然的,这事就落在jb身上; 安全

image.png-269.6kB

使用第三方工具

不幸中的万幸,以前这块是一测试妹子负责,当时让其写了个文档,总算有迹可循,一块儿看看目前我司是如何打渠道包的吧;bash

官网包闭包

先须要一个官网包,能够理解base包,适用于官网下载或者APP内手动、自动更新这些场景;app

360加固工具

有了官网包,而后就须要打渠道包的工具,我司用的是360加固工具;测试

连接:https://pan.baidu.com/s/1sPRt2vxdXegSBV_wEYH66A 
提取码:nu47
复制代码

下载解压,稍后下,还须要两个文件,签名文件keystore及密码、渠道文件gradle

两个文件准备好,打开exe、注册、登陆、添加信息(乱写便可),就会看到这货的界面;

image.png-27.7kB
image.png-135.6kB

点击应用加固-签名设置、多渠道设置,分别上传对应的keystore文件跟渠道文件;

image.png-45.6kB
image.png-84.6kB

而后点击添加应用,选择应用,而后就等着渠道包出来吧;

image.png-144kB
image.png-54.9kB

而后再手动去对应的渠道平台官网上传提交审核就能够了;

这个流程完,看着也很简单,没啥特别的,可是为啥要说这个事?

由于keystore不能随便给的啊!!!

既然如此,这种方式存在安全性问题,所以不建议使用,那怎么办?

没源码

在没有源码的事情下,想到的就是反编译,而平常用的最多的就是apktool工具;

流程是这样的:

  • 有base apk;
  • 复制一份新的apk;
  • 经过apktool工具,解压apk(apktool d XX.apk);
  • 添加渠道信息;
  • 经过ApkTool工具,从新打包生成新APK(apktool b newApkDir);
  • 从新签名;

这里说明几个点:

从新打包apk

apkapktool b newApkDir
复制代码

从新打包的apk会在newApkDir\dist下;

签名

这里有两种状况,没有签名跟有签名,当没有签名时,须要先生成keystore文件;

keytool -genkey -alias jb.keystore -keyalg RSA -validity 20000 -keystore jb.keystore
复制代码

输入后须要输入点内容:

image.png-119.4kB
这样,就会生成 jb.keystore文件;

有前面文件后,接下来就是签名了;

jarsigner -verbose -keystore jb.keystore -signedjar jb_signed.apk jb.apk jb.keystore
复制代码

这里说明下,jb.apk就是从新打包后的apk,jb_signed.apk就是要生成的apk;

这样,打出来的包就能够安装了,可是呢,依然依赖 keystore文件,若是别人的APP使用本身的 keystore,普通功能是没问题的,可是一旦须要登陆功能,就会报错,提示签名跟XX平台的签名不一致;

怎么解决这问题?直接xp,这里就不展开了;

本身搞呗

本身搞的前提是得有源码,若是连代码权限都没有,那就放弃吧;

而下面的例子只会使用demo来简单演示;

传统的作法

只有一个渠道标识

AndroidManifest.xmlhardcode对应的曲奥标识;

<meta-data android:value="jbtest" android:name="CHANNEL"/>
复制代码

多个渠道标识

AndroidManifest.xml添加渠道信息占位符;

<meta-data android:name="CHANNEL"  android:value="${CHANNEL}" />
复制代码

build.grade设置productFlavors标签添加渠道信息:

android{
     productFlavors{    
        "jb"{
             manifestPlaceholders = [CHANNEL : "jb"]
         }    
         "jb2"{
             manifestPlaceholders = [CHANNEL : "jb2"]
         }
     }
 }
复制代码

这样,Gradle编译生成多渠道包时,会用不一样的渠道信息替换AndroidManifest.xml中的占位符;

缺点很明显,每生成一个渠道包,都要从新执行构建流程,国内渠道如此丰富,效率过低了;

美团Walle

这是落魄安卓同窗提供的,github地址点这里

虽然github里面把每一步都讲的很清楚,可是由于懒,因此仍是想这里贴一下gradle接入的步骤:

1.修改项目根目录下build.gradle文件,在buildscript下的dependencies中增长:

classpath 'com.meituan.android.walle:plugin:1.1.6'
复制代码

完整以下:

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        classpath 'com.meituan.android.walle:plugin:1.1.6'
        
    }
}
复制代码

2.修改app工程的build.gradle文件,增长以下信息:

1)头部增长:

apply plugin: 'walle'
复制代码

2)须要在buildTypes中加signingConfig,不然报这个错: Error:Plugin requires 'APK Signature Scheme v2 Enabled' for release.

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug
        }
    }
复制代码

这里说明下signingConfig,是须要一个keystore,对这块有疑问的同窗,请点击这里查看;

3)配置wallet信息

walle {
    // 指定渠道包的输出路径
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定制渠道包的APK的文件名称
    apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // 渠道配置文件
    channelFile = new File("${project.getProjectDir()}/channel")
}
复制代码

4)dependencies新增 compile:

dependencies {
    implementation 'com.meituan.android.walle:library:1.1.6'
}
复制代码

完整的APP下的build.grade内容以下:

apply plugin: 'com.android.application'
apply plugin: 'walle'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.jb.myapplication"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug
        }
    }
}
walle {
    // 指定渠道包的输出路径
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定制渠道包的APK的文件名称
    apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // 渠道配置文件
    channelFile = new File("${project.getProjectDir()}/channel")
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.meituan.android.walle:library:1.1.6'
}


复制代码

3.添加 channel 渠道文件

直接在APP目录下添加名为channel的文件,内容是须要的渠道信息;

anzhuo
anfen
anbei
PC6
360
yingyongbao
baidu
wandoujia
pp
xiaomi
oppo
lenovo
huawei
复制代码

4.获取渠道

在须要获取渠道信息的地方使用以下代码获取渠道信息:

String channel = WalleChannelReader.getChannel(this.getApplicationContext());
复制代码

4.获取渠道

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

生成渠道包      
gradlew clean assembleReleaseChannels

支持 productFlavors 
gradlew clean assembleMeituanReleaseChannels

生成单个渠道包  
gradlew clean assembleReleaseChannels -PchannelList=anzhuo

生成多个渠道包  
gradlew clean assembleReleaseChannels -PchannelList=wandoujia,baidu

Mac的话,就是./gradlew;
复制代码

原理

原理的话,就是在META-INF目录内添加空文件,能够不用从新签名应用,经过为不一样渠道的应用添加不一样的空文件,能够惟一标识一个渠道;

每打一个渠道包只需复制一个apk,在META-INF中添加一个使用渠道号命名的空文件便可;

这块的话,网上有大神把脚本开源了,网站自个儿找下吧;

zhuanlan.zhihu.com/p/26674427

一些经常使用方法

须要的一些环境跟工具,请本身网上了解配置吧;

查看apk是否签名

使用的是jarsigner命令;

jarsigner -certs -verbose -verify xxx.apk 
复制代码

image.png-21.9kB

查看apk的版本号

使用aapt命令;

aapt dump badging xxx.apk
复制代码

image.png-140.7kB

查看apk的渠道号

反编译apk,jb用的是apktool工具,2.4.1版本;

连接:https://pan.baidu.com/s/1MPWTfXIGzeOUpGZplEkveA 
提取码:6h08
复制代码
apktool d XX.apk
复制代码

而后会生成一个目录,直接找到AndroidManifest.xml文件,通常经常使用的是友盟,所以直接搜索UMENG_CHANNEL,若是用的是别的,请自行搜索;

image.png-9.9kB

实践

凡事都须要落地,那如何落地?

上面的方案,毫无疑问是选择第三种,实践也很简单,直接在jenkins新增打渠道包的选项便可

小结

本文主要是经过3种方式来说述安卓多渠道包的方式,旧内容,对没了解过的同窗有必定的帮助,就这样吧~

1-140R3154U8.jpg-9kB
相关文章
相关标签/搜索