多渠道打包,生成不同包名的包

来对多渠道打包,并生成不同的包名的知识点做个总结。需要生成不同包名的原因是为了运营的ASO。

方法:

1.直接建立渠道的文件夹,修改Manifest里面的包名

2.利用占位符

当然上面两种方法各有优劣,最后说一下他们的各自的一些特点。

首先来说第一种方法,步骤:

1.根据需要生成多少个包名的包建立和main同级的文件夹。

例如:我这里需要两个不同包名的包,那就需要建立两个不同渠道的文件夹。

2.在文件夹里面新建Maifest文件

因为包名是在Manifest文件里面定义的,所以需要建立Manifest文件,当然这个Manifest文件里面拷贝过来,你可能会觉得太麻烦,我只是替换一个包名需要把整个Manifest都拷贝过来么,这也太坑了,其实没有这么严重,包名一般包括在用户手机桌面上面显示的名字,和你去应用程序管理器里面看到的名字,这两个名字是可以不同的。

在应用程序管理器里面显示的名字是由application节点的android:label属性决定的。

用户手机桌面上面显示的名字是由应用程序的第一个Activity的android:label决定的,如果第一个Activity没有指定label属性的话,就是使用的Application的android:label的名字。

顺便提一句,应用程序的第一个Activity是有下面的intent-filter的Activity。

<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

这里我们明白了,应用程序的两个包名,那么既然我们需要改变的只是包名而已,就只需要把application节点和第一个Activity在Manifest里面的配置拷贝过来就可以了

所以这里需要的两个Manifest文件分别是这样的:

先贴一下main渠道的主的Manifest文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.name.replace"
xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        ...
        其他配置
        ...
    </application>
</manifest>

app_name_1渠道:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.name.replace"
xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name_1"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:label">
        <activity
            android:name=".MainActivity"
            android:label="@string/desk_name_1"
            tools:replace="android:label">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

app_name_2渠道:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.name.replace"
xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name_2"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:label">
        <activity
            android:name=".MainActivity"
            android:label="@string/desk_name_2"
            tools:replace="android:label">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

这里可以看到app_name_1里面的Manifest和app_name_2里面的Manifest并没有太大的差别,只是包名改了一下而已。这两个文件没有什么可比较的价值。

着重看一下app_name_2渠道的Manifest和main里面的Manifest的差别,如果你说没有差别,那就比较尴尬了,妈蛋,我450度的眼镜都看出差别了。

两个差别:

(1).在app_name_2的渠道里面引入了新的tools命名空间。

xmlns:tools=”http://schemas.android.com/tools”

并且在application节点和第一个Activity节点添加了tools:replace=”android:label”语句。

如果没有添加Gradle在使用Manifest Merger Tool进行合并Manifest的时候出出问题。

(2).app_name_2渠道除了application节点和第一个Activity节点之外,没有其他的东西。

不需要main里面的其他的一些四大组件相关的一些东西。

3.在build.gradle里面配置渠道信息

    productFlavors {
        app_name_1 {}
        app_name_2 {}
        app_main {}
        }

这里的渠道名要和一开始建立的文件夹的名字一样,如果不一样,打出的包就是main里面的包。

4.打包即可




第二种方法,步骤:

得益于gradle对于占位符的支持,第二种方法远没有第一种方法那么麻烦。

关于占位符的用法有很多,比如可以动态的定义Activity的名字,Service的名字等。详细的可以自行Google。

关于gradle的清单合并可以看这一篇翻译的文章,讲解的非常详细:

清单合并:http://blog.csdn.net/maosidiaoxian/article/details/42671999

1.在Manifest里面配置占位符

由于不需要建立文件夹,这里说的Manifest就是main里面的Manifest。

当属性值包含一个占位符时,合并工具将把此占位符的值换成一个注入的值。注入的值是在build.gradle里面定义的。

占位符值的语法是 ${name},因为@符号已经预留给了链接。在最后的文件合并发生之后,并且生成合并后的 android 的清单文件输出之前,带有占位符的所有值将都会被替换为注入的值。如果变量名是未知的,将导致构建失败。

Manifest文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.name.replace"
xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="${app_name}"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${umeng_channel}"/>
        <activity
            android:name=".MainActivity"
            android:label="${desk_name}">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

这里定义了三个占位符,app_name,desk_name,umeng_channel。

占位符可以替换的还有很多用处,想了解更多的可以自己查资料。

2.在build.gradle里面配置渠道信息

这里贴出整个Manifest文件,供大家更好的看清。

apply plugin: ‘com.android.application‘
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    defaultConfig {
        applicationId "com.name.replace"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        manifestPlaceholders = [
                app_name     : "@string/app_name",
                desk_name    : "@string/app_name",
                umeng_channel: "测试版"
        ]
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
        }
    }
    productFlavors {
//        app_name_1 {}
//        app_name_2 {}
//        app_main {}
        app_qq {
            manifestPlaceholders = [
                    app_name     : "@string/app_name_1",
                    desk_name    : "@string/desk_name_1",
                    umeng_channel: "应用宝"
            ]
        }
        app_pp {
            manifestPlaceholders = [
                    app_name     : "@string/app_name_2",
                    desk_name    : "@string/desk_name_2",
                    umeng_channel: "pp助手"
            ]
        }
    }
}
dependencies {
    compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
    testCompile ‘junit:junit:4.12‘
    compile ‘com.android.support:appcompat-v7:23.3.0‘
}

可以看到我们对Manifest里面定义的三个占位符做了替换。

这里我们既在defaultConfig里面定义了,又在不同的渠道里面做了再次定义,最后渠道里面的优先级会高。

其实如果一开始没有配置渠道信息,但是我们定义了占位符的话,是编译不过去的,必须在defaultConfig里面定义默认的一些属性。

3.打包即可

最开始的时候我们说了这两种方法各有优缺点,在以前的公司的时候采用的是第一种方案,原因有两点:

1.采用第一种方案,可以对每个渠道加上渠道的logo,比如360的渠道需要360的logo,百度的渠道需要百度的logo,那么采用第一种方法就很好实现了,把main里面的res/layout里面的启动界面拷贝一份到对应的渠道文件里面进行修改,替换logo。

第一种方法里面不止可以放置Manifest文件,还可以放置res目录。

2.当时的渠道包不需要我们技术人员去打,由运营去打,技术这边当时是开发了一个工具供运营那边打渠道包专用,技术这边只需要打好不同的包名的包即可。

所以第一种方法的优点是可以完成一些其余的特殊的操作,缺点是比较麻烦。第二种方法是实现比较简单,但是有些特殊的操作就不能行了。

Demo地址:http://download.csdn.net/detail/qy274770068/9498668

时间: 2024-08-03 21:51:14

多渠道打包,生成不同包名的包的相关文章

通过项目下的包名获取包下的全部类

通过项目下的包名获取包下的全部类 public class GetClasses { public static Set<Class<?>> classes = new HashSet<>(); public static void main(String[] args) { GetAllClass("com.bihang.seayatest.nio"); System.out.println(classes.size()); } public st

关于maven环境下使用pom.xml引入包名.lastUpdate包的解决办法

今天在导入POI-OOXML的时候老师缺失xmlbeans包,而且刷新pom文件总是生成一个lastupdate文件,大小为1KB,终于找到解决办法. 1.首先删除想要的jar包所在文件夹内的所有 .lastUpdate的文件,并下载需要的jar包放入相应的文件夹内. 2.在eclipse中依次打开window->showview->other,找到maven 3.选择Maven库点击ok,在console一栏找到maven库的界面 4.在本地仓库右键,重新绑定索引,这样就能在pom.xml中

Spring根据包名获取包路径下的所有类

参考mybatis MapperScannerConfigurer.java 最终找到 Spring的一个类  ClassPathBeanDefinitionScanner.java 参考ClassPathBeanDefinitionScanner 和它的父类 ClassPathScanningCandidateComponentProvider,将一些代码进行抽取,得到如下工具类. import org.apache.commons.lang3.ArrayUtils; import org.s

java基础知识之一:命名规则(包名、类名、变量名、方法名)

1.包名:包名一般是小写英文字母 2.类名:单词首字母大写 3.变量名: 1) 标识符由字母.数字.下划线"_".美元符号"$"或者人民币符号"¥"组成,并且首字母不能是数字. 2) 不能把关键字和保留字作为标识符. 3) 标识符没有长度限制. 4) 标识符对大小写敏感. 4.方法名:首单词小写,后面单词首字母大写 注意一下,不同变量类型默认的字节存储.Java中小数默认是double类型,例如上面(float)4.5,如果你直接写4.5,会在4

自动化瓦力多渠道打包python脚本

自动化瓦力多渠道打包python脚本 目录介绍 1.本库优势亮点 2.使用介绍 3.注意要点 4.效果展示 5.其他介绍 0.首先看看我录制的案例演示 如下所示,这段python代码很简单,工具十分强大,一键多渠道打包工具. 项目的开源地址:https://github.com/yangchong211/YCWalleHelper 1.本库优势亮点 通过该自动化脚本,自需要run一下或者命令行运行脚本即可实现美团瓦力多渠道打包,打包速度很快 配置信息十分简单,代码中已经注释十分详细.Keysto

Linux学习总结(九)-源码包和rpm包安装

我们熟悉下linux 软件安装:https://zhidao.baidu.com/question/504980243.html这里写了源码安装和yum安装的优缺点,可以看看 一.源码包安装 通常办法是安装三部曲:./configuremakemake install但是具体还要根据包里面的帮助文档操作./configure --help 可以查看可以带什么参数,比如--prefix=/usr/local可以指定安装目录源码包安装最容易碰到包依赖问题,这也是提高解决问题能力的过程,避无可避2 编

yum更换国内源/下载rpm包 源码包安装

一.yum更换国内源#cd /etc/yum.repos.d/#rm -f CentOS-Base.repo#curl -O http://mirrors.163.com/.help/CentOS-Base-163.repo#yum list二.yum下载rpm包#yum install -y epel-release#yum list |grep epel#yum install 包名 --downloadonly //仅仅下载不安装#rpm -q 包名 //检测包有没有被安装#ls /var

Phonegap(cordova)创建项目,并结合eclipse开发工具进行打包生成apk包

1.使用phonegap(cordova)创建并编辑项目 (1)创建一个文件夹用于存放稍后创建的Android程序,这里我们在E盘创建了一个文件夹AndroidProject,适用cd命令进入该目录,接下来适用phonegap命令创建对应的android项目. phonegap的创建指令:  phonegap create hello com.example.hello HelloWorld hello:你的项目文件夹名称,   com.example.hello:你的项目内部包名   Hell

android studio 多渠道打包,调试正式包,build.gradle解析

1,讲解build.gradle文件. 1.1根目录Android 1.1.1 defaultConfig是Android的根目录,可以配置包名等信息,若AndroidMainfest.xml也配置了,以defaultConfig的为准. 1.1.2 signingConfigs是Android的根目录,可以配置签名,如下图: 调试时若想直接用正式的签名包可以在buildType里配置. buildTypes { debug { signingConfig signingConfigs.rele