This paper first reviews the popular multi-channel packaging method in the past, and then introduces the Packer-ng-plugin project of McXiaoke, and introduces how to solve the more convenient Multi-channel packaging problem of Android in the practical application (with umeng statistics)

Multi-channel packaging scheme analysis

Android app market is diverse, app Treasure, Mi market, Wandoujia… In order to monitor our app downloads and distribution in each market, branding the APK that is released in each market is a necessary step. This is the issue of multi-channel APK. “Channel” is branding the APK. At the same time, Umeng statistics can help us to collect Channel data, which is convenient for product managers to make next product decisions after data analysis.

At present, there are roughly several multi-channel packaging methods:

  1. Gradle is built with productFlavor. See my previous blog
  2. Apktool resignature and repackage
  3. Write an empty file named channel number to meta-INF folder in apK file

The third way is relatively fast, it is said that more than 900 channels can be completed in less than a minute, for reference. The downside is that you need to maintain a Python script that writes an empty file named after the channel name for each channel.

Since apK is a zip file, there is a section at the end of the zip file that can be used as a comment to the zip file. Properly modifying this section will not damage the ZIP file. Using this field, we can add some custom data. This is where the PackerNg project adds and reads channel information. It also provides an interface for reading channel information.

Practical application integration

Modify project gradle and add

buildscript { ...... Dependencies {/ / add packer - ng classpath 'com. McXiaoke. Gradle: packer - ng: 1.0.5'}}Copy the code

Modify moudle gradle and add it

Apply the plugin: 'packer' dependencies {/ / add packer - helper compile 'com. McXiaoke. Gradle: packer - helper: 1.0.5'}Copy the code

Note: The pack-ng and Pack-Helper versions must be the same

Add a channel listing file to your project root directory, such as “market. TXT” and”

YingYongBao
XiaoMi
WanDouJia
Baidu
Qihoo
GooglePlay
...Copy the code

That is, each line is a channel number

Add a bat script (Windows) to the root of your project, such as build.bat, that says (a command)

gradle -Pmarket=markets.txt clean apkReleaseCopy the code

Packer-ng-plugin will automatically help you build each package according to market. TXT, as long as you enter your root directory and double-click the bat script, packer-ng-plugin will automatically help you build each package according to market. Alternatively, you can execute build.bat directly in Android Studio’s Terminal.

Looking at the console output, packer-ng eventually forms gradle tasks for each channel package:

. :app:apkRelease processed apk for XiaoMi (4) :app:apkRelease processed apk for WanDouJia (5) :app:apkRelease processed apk for Baidu (6) :app:apkRelease processed apk for Qihoo (7) :app:apkRelease processed apk for GooglePlay (8) :app:apkRelease all 8 apks saved to D:\workspace\shine\build\archives :app:apkRelease PackerNg: Market Packaging Successful! BUILD SUCCESSFUL Total time: 1 mins 23.269 SECsCopy the code

From this output, he generated a total of eight channel packages, all of which were in the build/ Archives folder in the project root directory

Packer-ng-plugin also provides some custom configurations, such as the naming of the input APK (refer to the plug-in configuration instructions), as well as Java and Python command-line scripts for integration into a continuous integration environment (refer to command line packaging scripts).

The last point is how to let UmENG statistics know which channel apK is currently. First you need to remove the previous productFlavor or manifest code in the way of placeholders, remove the META Data configuration of the Friends Channel in the AndroidManifest. Then add the following code to the onCreate Application:

final String market = PackerNg.getMarket(this,"defaul_channel); AnalyticsConfig.setChannel(market); //AnalyticsConfig is a code way to set channel classCopy the code