Android product Development (five)-multi-channel packaging

Source: Internet
Author: User

The domestic Android developers are still very hard, because of the well-known reasons, Google Play can no longer open in the country, so the Android system application market, the supremacy of hegemony, and the consequences of the domestic existence there are many application markets, products in different channels may have this different statistical needs, For this reason, Android developers need to release an installation package for each app market, which involves multi-channel packaging for Android.

This paper mainly explains several kinds of mainstream multi-channel packaging, and its advantages and disadvantages.

    • Multi-channel packaging by configuring Gradle scripts

This packaging method is used in conjunction with the build tool Gradle of Android Studio, The core principle is to modify the Mate-date content in Androidmanifest.xml through the script, and execute the N-pack signature operation to realize multi-channel packaging requirements, and realize the following.

(i) Defining mate-data tags in androidmanifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"        package="your.package.name">        <application>              <meta-data android:name="UMENG_CHANNEL" android:value="{UMENG}"/>        </application>    </manifest>   

It is important to note that the value above should correspond to the channel name, such as the channel name for your pea pod in Wandoujia.

(ii) The PRODUCTFLAVORS definition channel number under Build.gradle:

productFlavors {          internal {}          /*InHouse {}          pcguanwang {}          h5guanwang {}          hiapk {}          m91 {}          appchina {}          baidu {}          qq {}          jifeng {}          anzhi {}          mumayi {}          m360 {}          youyi {}          wandoujia {}          xiaomi {}          sougou {}          leshangdian {}          huawei {}          uc {}          oppo {}          flyme {}          jinli {}          letv {}*/          productFlavors.all { flavor ->               flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]          }      }  

Also note that you need to configure a default channel name in Defaultconfig

manifestPlaceholders = [UMENG_CHANNEL_VALUE: "channel_name"]  

Implement multi-channel packaging to replace content in Mate-data tags

Advantages: Convenient and flexible, can be configured according to their own needs of different channels to carry out different logic;
Disadvantage: Packaging speed is too slow;

    • Using third-party packaging tools

This way is the use of third-party services, such as 360, Baidu, friends, etc., its principle is to modify the androidmanifest.xml in the mate-data tag content, and then perform N-pack signature operation to achieve multi-channel packaging. Here is not to do a specific explanation, so as to avoid the suspicion of advertising, O (∩_∩) o haha ~.

Advantages: Simple and convenient, almost do not do what their own work;
Disadvantage: Packaging speed is too slow;

    • Use the multi-channel packaging method of American group

And here is mainly based on the United States Group Client packaging Experience (see: American Group Android Automation Tour-Generate channel package)
The main introduction is to use the Meta-inf directory to add empty files in a way to achieve bulk rapid packaging Android applications.

Implementation principle

Android App install package apk file is actually a compressed file that can be modified to zip direct decompression. After extracting the installation files, you will find a meta-inf directory in the root directory. If you add an empty file within the Meta-inf directory, you do not have to re-sign the app. Therefore, you can uniquely identify a channel by adding different empty files for different channels of application.
"In this way, one channel package per dozen only needs to copy an apk and add an empty file named with the channel number in Meta-inf. This packaging is very fast, and more than 900 channels can be played in less than a minute. ”

Implementation steps

(i) Preparation of channel number files

(ii) Write a Python script to extract the apk file, add files for the Meta-inf directory, and re-compress the APK file and other logic:

# Coding=utf-8ImportZipFileImportShutilImportOs def delete_file_folder(src):      "Delete files and folders "     ifOs.path.isfile (SRC):Try: Os.remove (SRC)except:Pass     elifOs.path.isdir (SRC): forIteminchOs.listdir (SRC): Itemsrc=os.path.join (Src,item) Delete_file_folder (ITEMSRC)Try: Os.rmdir (SRC)except:Pass# Create an empty file, this file as an empty file in the APK packageSrc_empty_file =' Info/empty.txt 'f = open (Src_empty_file,' W ') F.close ()# in the channel number configuration file, get the specified channel numberChannelfile = open ('./info/channel.txt ',' R ') channels = Channelfile.readlines () channelfile.close () print ('-'* -,' All channels ','-'* -) print (channels) print ('-'* -)# Get all the apk files in the current directorySrc_apks = []; forFileinchOs.listdir ('. '):ifOs.path.isfile (file): Extension = os.path.splitext (file) [1][1:]ifExtensioninch ' apk ': Src_apks.append (file)# Traverse so the apk file to add the channel number file to its compressed file forsrc_apkinchSrc_apks:src_apk_file_name = Os.path.basename (src_apk) print (' current apk name: ', src_apk_file_name) temp_list = Os.path.splitext (src_apk_file_name) src_apk_name = temp_list[0] Src_apk_extension = temp_list[1] Apk_names = Src_apk_name.split ('-'); Output_dir =' OutputDir '+'/'    ifOs.path.exists (Output_dir): Delete_file_folder (Output_dir)if  notOs.path.exists (Output_dir): Os.mkdir (Output_dir)# Iterate through the channel number obtained from the file and write it into the APK package     forLineinchChannels:target_channel = Line.strip () target_apk = Output_dir + apk_names[0] +"-"+ target_channel+"-"+apk_names[2] + src_apk_extension shutil.copy (src_apk, target_apk) zipped = ZipFile. ZipFile (target_apk,' A ', ZipFile. zip_deflated) Empty_channel_file ="Meta-inf/uuchannel_{channel}". Format (channel = Target_channel) Zipped.write (Src_empty_file, Empty_channel_file) zipped.close () print ('-'* -) Print (' repackaging is over, total package: ', Len (Channels)) input (' \npackage over ... ')

(c) Pack a normal APK package
(iv) Execute Python scripts, multi-channel packaging
(v) Get channel number in Android code

/** * Channel number Tool class: Parse the compressed package to get the channel number */ Public  class channelutil {    Private Static FinalString Channel_key ="Uuchannel";Private Static FinalString Default_channel ="Internal";Private StaticString Mchannel; Public StaticStringGetchannel(Context context) {returnGetchannel (context, default_channel); } Public StaticStringGetchannel(context context, String Defaultchannel) {if(! Textutils.isempty (Mchannel)) {returnMchannel; }//Get from APKMchannel = getchannelfromapk (context, channel_key);if(! Textutils.isempty (Mchannel)) {returnMchannel; }//Get all failed        returnDefaultchannel; }
    /** * Get version information from APK * * @param context * @param channelkey * @return */    Private StaticStringgetchannelfromapk(context context, String Channelkey) {LongStartTime = System.currenttimemillis ();//Get from APK packageApplicationInfo appinfo = Context.getapplicationinfo (); String SourceDir = Appinfo.sourcedir;//default in meta-inf/, so you need to stitch it up again.String key ="meta-inf/"+ Channelkey; String ret =""; ZipFile ZipFile =NULL;Try{ZipFile =NewZipFile (SourceDir); enumeration<?> entries = Zipfile.entries (); while(Entries.hasmoreelements ())                {ZipEntry entry = ((ZipEntry) entries.nextelement ()); String entryName = Entry.getname ();if(Entryname.startswith (key)) {ret = EntryName; Break; }            }        }Catch(IOException e)        {E.printstacktrace (); }finally{if(ZipFile! =NULL) {Try{Zipfile.close (); }Catch(IOException e)                {E.printstacktrace (); }}} String Channel ="";if(! Textutils.isempty (ret)) {string[] split = Ret.split ("_");if(Split! =NULL&& Split.length >=2) {channel = Ret.substring (split[0].length () +1); } System.out.println ("-----------------------------"); System.out.println ("channel number:"+ Channel +", extracting the channel number takes time:"+ (System.currenttimemillis ()-startTime) +"MS"); System.out.println ("-----------------------------"); }Else{System.out.println ("not resolved to the appropriate channel number, using the default internal channel number");        Channel = Default_channel; }returnChannel }}

This is how the entire packaging process works, and the work tool can refer to the project on GitHub: multi-channel packaging implementation

Advantages: Packaging speed quickly, very convenient;
Disadvantage: Not flexible enough, can not flexibly configure different channels of different business logic;

Problem:
Due to the use of Friend League statistics in the project, previously, the channel information was saved in Meta-data, and now you need to manually execute the channel number setup code after changing the mode:

String channel = ChannelUtil.getChannel(mContext);        System.out.println("启动页获取到的渠道号为:" + channel);        // 设置友盟统计的渠道号,原来是在Manifest文件中设置的meta-data,现在启动页中设置        AnalyticsConfig.setChannel(channel);

This packaging method previously required one hours of packaging work now only takes a minute, greatly improved efficiency, currently in the actual application has not found any problems, the need for children's shoes can try.

Summarize

Although we summarize three kinds of packaging methods, but in fact, through the Gradle packaging and use of third-party services packaging is the implementation of the N-pack signature operation, time consuming too much, so not recommended, and the United States of America's way in the efficiency of a lot of improvement, But for that different channel package to perform different business logic requirements of incompetence as an example, only through Gradle configuration, so everyone in the choice of multi-channel packaging method can be based on their own needs to choose.

In addition to product development technology, skills, practice interested students can refer to my:
Android Product Development (i) –> Practical development Code
Android product Development (ii) –> start Page optimization
Android Product Development (iii) –> base class activity
Android product Development (iv) –> reduce APK size

This article synchronizes to GitHub: Https://github.com/yipianfengye/androidProject, Welcome to star and follow

Android product Development (five)-multi-channel packaging

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.