多渠道打包

最近由于要独立开发,所以需要掌握从开发到上线的所有阶段,以前从没接触过打包的问题,现在突然接触感觉手忙脚乱的,特此总结一下。
国内的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进行对其操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值