多渠道打包

来源:互联网 发布:linux如何查看ssh端口 编辑:程序博客网 时间:2024/06/06 03:59

最近由于要独立开发,所以需要掌握从开发到上线的所有阶段,以前从没接触过打包的问题,现在突然接触感觉手忙脚乱的,特此总结一下。
国内的Android开发由于众所周知的原因,Google play无法在国内打开,所以android的市场群雄争霸,为了方便统计各个安卓市场的下载量,需要为每个应用市场的Android包设定一个可以区分应用市场的标识,这个为Android包设定应用市场标识的过程就是多渠道打包。
其实感觉多渠道打包就是一个换应用名字的过程,但是换了应用名字谁也不知道该如何统计,为了能让友盟统计到下载量,就需要在AndroidManifest.xml中的mate-date改变渠道号的标识,这样才能让友盟根据渠道号统计到下载量。由于android7.0修改了签名机制,感觉最纯正的打包方式还是使用gradle。
仔细搜一下的话还是发现了很多写好的gradle代码,方法都大同小异,去将每一个包的渠道号修改掉,并动态获取此时的包名,这也是因为友盟的渠道号只能在代码中去注册。

apply plugin: 'com.android.application'android {    compileSdkVersion 23    buildToolsVersion "23.0.3"    defaultConfig {        applicationId "com.wooyun.castiel"        minSdkVersion 15        targetSdkVersion 23        versionCode 1        versionName "1.0"    }     //签名    signingConfigs {        debugConfig {            storeFile file("../wooyun_keystore")      //签名文件            storePassword "123456"            keyAlias "123456"            keyPassword "123456"  //签名密码        }        release{            storeFile file("../wooyun_keystore")      //签名文件            storePassword "123456"            keyAlias "123456"            keyPassword "123456"  //签名密码        }    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            // 自定义输出配置            applicationVariants.all { variant ->                variant.outputs.each { output ->                    def outputFile = output.outputFile                    if (outputFile != null && outputFile.name.endsWith('.apk')) {                        // 输出apk名称为wooyun_v1.0_wandoujia.apk                        def fileName = "wooyun_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"                        output.outputFile = new File(outputFile.parent, fileName)                    }                }            }        }    }    productFlavors {        kuan {}        xiaomi {}        qh360 {}        baidu {}        wandoujia {}    }    productFlavors.all {        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:23.4.0'}
/** * 渠道号工具类:解析压缩包,从中获取渠道号 */public class ChannelUtil {    private static final String CHANNEL_KEY = "uuchannel";    private static final String DEFAULT_CHANNEL = "internal";    private static String mChannel;    public static String getChannel(Context context) {        return getChannel(context, DEFAULT_CHANNEL);    }    public static String getChannel(Context context, String defaultChannel) {        if (!TextUtils.isEmpty(mChannel)) {            return mChannel;        }        //从apk中获取        mChannel = getChannelFromApk(context, CHANNEL_KEY);        if (!TextUtils.isEmpty(mChannel)) {            return mChannel;        }        //全部获取失败        return defaultChannel;    }/**     * 从apk中获取版本信息     *     * @param context     * @param channelKey     * @return     */    private static String getChannelFromApk(Context context, String channelKey) {        long startTime = System.currentTimeMillis();        //从apk包中获取        ApplicationInfo appinfo = context.getApplicationInfo();        String sourceDir = appinfo.sourceDir;        //默认放在meta-inf/里, 所以需要再拼接一下        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 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 + ",解压获取渠道号耗时:" + (System.currentTimeMillis() - startTime) + "ms");            System.out.println("-----------------------------");        } else {            System.out.println("未解析到相应的渠道号,使用默认内部渠道号");            channel = DEFAULT_CHANNEL;        }        return channel;    }}

android打包的过程也是一个很值得研究的地方,主要分为七步
1.打包资源文件,生成R.java文件
2.处理aidl文件,生成相应Java文件。
3.编译工程源代码,生成相应class文件。
4.转换所有class文件,生成class.dex文件
5.打包生产apk
6.对apk文件进行签名
7.对签名的apk进行对其操作。

原创粉丝点击