Meituan multi-channel packaging and Meituan Packaging
I. Principles
Decompress an Android app package as a zip package and find that adding an empty file under the directory (META-INF) generated by the signature does not require a re-signature. Using this mechanism, the file name is the channel name. This method does not require re-signature or other steps, which is very efficient.
Ii. Method
You have saved the Meituan packaging tool to the test01 file under tools:
1. Put the apk to be packaged in PythonTool.
2. Write the required channel to PythonTool/info/channel.txt. One channel occupies one line.
3. Double-click to execute the PythonTool/MultiChannelBuildTool. py file (Python environment is required), and a channel package will be generated.
4. Obtain channel information: Copy ChannelUtil. java from the JavaUtil file to the project, and call ChannelUtil. getChannel to obtain the channel information.
Package com. czt. util; import java. io. IOException; import java. util. enumeration; import java.util.zip. zipEntry; import java.util.zip. zipFile; import android. content. context; import android. content. sharedPreferences; import android. content. sharedPreferences. editor; import android. content. pm. applicationInfo; import android. content. pm. packageManager. nameNotFoundException; import android. preference. preferenceMana Ger; import android. text. textUtils; public class ChannelUtil {private static final String CHANNEL_KEY = "cztchannel"; private static final String CHANNEL_VERSION_KEY = "cztchannel_version"; private static String mChannel;/*** return to the market. If the query fails, return "* @ param context * @ return */public static String getChannel (Context context) {return getChannel (context ,"");} /*** return to the market. Return defaultChannel * @ param context * @ param defaultChannel * @ return */public static String getChannel (Context context, String defaultChannel) {// get if (! TextUtils. isEmpty (mChannel) {return mChannel;} // get mChannel = getChannelBySharedPreferences (context) in sp; if (! TextUtils. isEmpty (mChannel) {return mChannel;} // obtain mChannel = getchannelfromapks (context, CHANNEL_KEY) from apk; if (! TextUtils. isEmpty (mChannel) {// Save the backup saveChannelBySharedPreferences (context, mChannel); return mChannel ;}// failed to get all return defaultChannel ;} /*** obtain the version information from apk * @ param context * @ param channelKey * @ return */private static String getchannelfromusk (Context context, String channelKey) {// obtain ApplicationInfo appinfo = context from the apk package. getApplicationInfo (); String sourceDir = appinfo. sourceDir; // The default value is meta-inf/ So you need to splice String key = "META-INF/" + channelKey; 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 (key) {ret = entryName; break ;}} catch (IOException e) {e. printStackTrace ();} finally {if (zipfile! = Null) {try {zipfile. close ();} catch (IOException e) {e. printStackTrace () ;}} String [] split = ret. split ("_"); String channel = ""; if (split! = Null & split. length> = 2) {channel = ret. substring (split [0]. length () + 1);} return channel;}/*** Save the channel locally & corresponding version * @ param context * @ param channel */private static void saveChannelBySharedPreferences (Context context, string channel) {SharedPreferences sp = PreferenceManager. getdefasharsharedpreferences (context); Editor editor = sp. edit (); editor. putString (CHANNEL_KEY, channel); editor. putInt (C HANNEL_VERSION_KEY, getVersionCode (context); editor. commit ();} /*** get channel from sp * @ param context * @ blank return indicates an exception is obtained, the value in sp has expired, and the value in sp does not exist */private static String getChannelBySharedPreferences (context context) {SharedPreferences sp = PreferenceManager. getdefasharsharedpreferences (context); int currentVersionCode = getVersionCode (context); if (currentVersionCode =-1) {// get error return "";} int versionCodeSaved = Sp. getInt (CHANNEL_VERSION_KEY,-1); if (versionCodeSaved =-1) {// the version number corresponding to the channel that is not stored locally // the first time it is used or the original storage version number returns "";} if (currentVersionCode! = VersionCodeSaved) {return "";} return sp. getString (CHANNEL_KEY, "");}/*** get the version number from the package information * @ param context * @ return */private static int getVersionCode (Context context) {try {return context. getPackageManager (). getPackageInfo (context. getPackageName (), 0 ). versionCode;} catch (NameNotFoundException e) {e. printStackTrace () ;}return-1 ;}}
Tool: http://pan.baidu.com/share/link? Required id = 1485267923 & uk = 4218015263 # list/path = % 2F
Iii. Advantages and Disadvantages
Advantages:
This packaging method is very fast. More than 900 channels can be completed in less than one minute.
Disadvantages:
1. google will not be available if you change packaging rules someday so that empty files are created in the META-INF need to be repackaged
2. Some unscrupulous channels can easily use tools to modify channels. If a channel provider gets profits through a combination of network hijacking and tampering channels, for program developers, there may be huge economic losses.