3 Ways to pack your Android multi-channel package

Source: Internet
Author: User

Ext.: http://tech.meituan.com/mt-apk-packaging.html

Android Automation Tour-Generate channel packs

Zhihu2014-06-13 10:06

Overview

Each time a new version is issued, the Android client will be distributed to various application markets, such as pea pods, 360 mobile phone assistants and so on. In order to count the effects of these markets (active number, next singular, etc.), there is a way to uniquely identify them.

The group purchase client is currently using the channel number ( channel ) to differentiate between different markets, and the code uses Config.channel variables to record the channel number. For example, in the Pea pod market, the channel number for the U.S.-China application is the wandoujia channel number for the 360 mobile phone assistant China-US group qihu360 . The client accesses the API with the channel number in the request parameter so that the background can then calculate the effect of the different channels.

Each time the release, the marketing department will provide a list of channels, and Android Rd will generate an equal amount of channel packages based on these channels. As the channels become more and more (more than 900 channels have been written as of this writing), the way the client hits the channel pack has been evolving, and this article details the package journey for the American mission.

Maven

MAVEN is a software project management and automated build tool, with the use of Android-maven-plugin plug-ins, as well as the Maven-resources-plugin plug-in can be easily generated channel package, below a brief introduction to the next packaging process, Please refer to the relevant documentation for more information on how to use Maven and plugins.

First, AndroidManifest.xml add the <application> following element to the node <meta-data> to define the source of the channel:

<!-- 使用Maven打包时会用具体的渠道号替换掉${channel} --><meta-data        android:name="channel"        android:value="${channel}" />

Once you have defined the channel source, you can then read the channel number when the program starts:

private String getChannel(Context context) {        try {            PackageManager pm = context.getPackageManager();            ApplicationInfo appInfo = pm.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);            return appInfo.metaData.getString("channel");        } catch (PackageManager.NameNotFoundException ignored) {        }        return "";    }

To replace AndroidManifest.xml the channel number defined by the file, you also need to pom.xml configure the resources plug-in in the file:

<resources>               <resource>        <directory>${project.basedir}</directory>        <filtering>true</filtering>        <targetPath>${project.build.directory}/filtered-manifest</targetPath>        <includes>            <include>AndroidManifest.xml</include>        </includes>    </resource></resources>

The preparation has been completed, and what is needed now is the actual channel number. The following script iterates through the list of channels, replacing and packaging them individually:

#!/bin/bashpackage(){    while read line    do        mvn clean        mvn  -Dchannel=$line package    done < $1}package $1

This approach is acceptable when there are few early channels, but the approach is no longer applicable as long as the channel grows slightly, because it is inefficient to execute the build process once per dozen packages.

Apktool

Apktool is a reverse engineering tool that you can use to decode (decode) and modify the resources in the APK. Next, you'll learn more about using Apktool to generate channel packages.

As with Maven packaging, you also need to AndroidManifest.xml define elements in the file <meta-data> and read the channel numbers in the manifest file when the app starts. Please refer to the above code for details.

Unlike Maven, it is no longer necessary to rebuild the project each time it is packaged. When packaging, just build an apk and build another channel package on top of that apk.

First, using the Apktool decode application, enter the following command in the terminal:

apktool d your_original_apk build

The above command decode the application file in the build directory, and the directory after decode is complete as follows:

Next, replace AndroidManifest.xml the channel number defined in the file, following a Python script:

import redef replace_channel(channel, manifest):    pattern = r‘(<meta-data\s+android:name="channel"\s+android:value=")(\S+)("\s+/>)‘    replacement = r"\g<1>{channel}\g<3>".format(channel=channel)    return re.sub(pattern, replacement, manifest)

Then, use Apktool to build an unsigned apk:

apktool b build your_unsigned_apk

Finally, use Jarsigner to re-sign the APK:

jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore your_keystore_path -storepass your_storepass -signedjar your_signed_apk, your_unsigned_apk, your_alias

The above is a method of packaging using Apktool, which enables batch generation of channel packages by using scripts. Unlike Maven, every dozen packages require a build process that is built once and saves time.

But the last few days, our channel package more and more, there are nearly 900 channels, the completion of all the channel package needs nearly 3 hours. Is there a quicker way to pack? And look at the next section.

Meta-inf

If you can directly modify the APK channel number, and do not need to re-sign can save a lot of packaging time. Fortunately, we have found this way. Directly unzip the apk, the extracted root directory will have a META-INF directory, as shown in:

If you META-INF add an empty file within the directory, you can not re-sign the app. Therefore, you can uniquely identify a channel by adding different empty files for different channels of application.

The following Python code is used to add an empty channel file to the APK, with the prefix of the channel name mtchannel_ :

import zipfilezipped = zipfile.ZipFile(your_apk, ‘a‘, zipfile.ZIP_DEFLATED) empty_channel_file = "META-INF/mtchannel_{channel}".format(channel=your_channel)zipped.write(your_empty_file, empty_channel_file)

After adding the empty channel file directory, the META-INFO directory has a more than one named mtchannel_meituan empty file:

You can then read the empty channel file name in the Java code:

public static String Getchannel (context context) {ApplicationInfo appinfo = Context.getapplicationinfo ();        String SourceDir = Appinfo.sourcedir;        String ret = "";        ZipFile zipfile = null;            try {zipfile = new ZipFile (SourceDir);            enumeration<?> entries = Zipfile.entries ();                while (Entries.hasmoreelements ()) {ZipEntry entry = ((ZipEntry) entries.nextelement ());                String entryName = Entry.getname ();                    if (Entryname.startswith ("Mtchannel")) {ret = EntryName;                Break        }}} catch (IOException e) {e.printstacktrace ();                } finally {if (ZipFile! = null) {try {zipfile.close ();                } catch (IOException e) {e.printstacktrace ();        }}} string[] split = Ret.split ("_"); if (split!)= null && split.length >= 2) {return ret.substring (split[0].length () + 1);        } else {return ""; }    }

This way, each dozen a channel package only need to copy an apk, in the META-INF add a channel number named empty file can be. This packaging is very fast, and more than 900 channels can be played in less than a minute.

Summarize

There are a total of three ways to hit the channel pack. At present, the Android team packaging basic use of a third way, the completion of packaging automation, freeing up the productivity of engineers, good and good.

The problem with packing is solved, but sometimes you need to customize the APK for different channels. Next talk about Android build tool Gradle, and how to use Gradle Custom channel package, please look forward to.

3 Ways to pack your Android multi-channel package

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.