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
相關文章
相關標籤/搜索