Android程序编译时更改包名
Android项目开发中有时候需要改动apk的包名,比如希望能同时安装测试/debug版本和正式版。比较容易的方法是在eclipse中右键点击项目,选择Android Tools->Rename Application Package。但是这样做比较麻烦,实际上我们也可以通过build脚本在打包时修改包名,方法如下。
- ant, 在build.xml中加入下面一段。
<target name="-package-resources" depends="-crunch"> <!-- only package resources if *not* a library project --> <do-only-if-not-library elseText="Library project: do not package resources..." > <aapt executable="${aapt}" command="package" manifestpackage="your pakcage name" versioncode="${version.code}" versionname="${version.name}" debug="${build.is.packaging.debug}" manifest="${out.manifest.abs.file}" assets="${asset.absolute.dir}" androidjar="${project.target.android.jar}" apkfolder="${out.absolute.dir}" nocrunch="${build.packaging.nocrunch}" resourcefilename="${resource.package.file.name}" resourcefilter="${aapt.resource.filter}" libraryResFolderPathRefid="project.library.res.folder.path" libraryPackagesRefid="project.library.packages" libraryRFileRefid="project.library.bin.r.file.path" previousBuildType="${build.last.target}" buildType="${build.target}" ignoreAssets="${aapt.ignore.assets}"> <res path="${out.res.absolute.dir}" /> <res path="${resource.absolute.dir}" /> <!-- <nocompress /> forces no compression on any files in assets or res/raw --> <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw --> </aapt> </do-only-if-not-library> </target>
2. maven,在maven的build插件中加入下面一句
<plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId> <version>3.6.0</version> ... <configuration> ... <renameManifestPackage>com.napa.bluelion.reading.xzhz</renameManifestPackage> .... </configuration> ... </plugin>
3. gradle, gradle已经考虑了我们这点需求,可以直接为测试和正式版打出两个不同包名的Apk
可以直接在android default config中指定包名
android { compileSdkVersion 15 defaultConfig { ... packageName: your package name testPackageName: your test package name } }
也可以指定不同的productFlavors
android { ... defaultConfig { minSdkVersion 8 versionCode 3001 } productFlavors { flavor1 { versionCode 3001 packageName: your packageName0 } flavor2 { minSdkVersion 2500 packageName: your package name1 } } }
注意事项。有时我们会在代码中通过如下方式动态获取资源文件的id来加载资源文件。
int resId = getResources().getIdentifier(resName, "drawable", getPackageName());
这里的getPackageName会在编辑java代码时被编辑成Manifest文件中指定的package名字,导致我们在打包是改了包名以后出现运行时错误,找不到对应的资源文件。这时我们需要通过下面的方式在运行时动态获取pacakge name。
String packageName = getResources().getResourcePackageName(R.string.app_name);//这里的R.string.app_name是一个已经存在的资源。 int resId = getResources().getIdentifier(resName, "drawable", packageName);
原理:应用的包名其实不同于java代码的package名字。他实际上是appt工具在把资源文件编译成二进制时候用来生成资源的唯一标识用的。aapt在打包资源的时候会读取manifest文件中的包名来生成资源标识。所以以上的修改方式也就是通过在编译打包时指定package名字实现的。
相关推荐
Nostalgiachild 2020-11-13
韩伟佳 2020-10-09
wuleihenbang 2020-09-16
zzqLivecn 2020-07-09
chenjinlong 2020-06-10
yinbaoshiguang 2020-06-09
sgafdsg 2020-06-04
ustcrding 2020-06-03
chenjinlong 2020-06-03
AndroidGA 2020-06-01
安辉 2020-05-27
绿豆饼 2020-05-26
CNETNews 2020-05-26
xilove0 2020-05-12
绿豆饼 2020-05-12
ChainDestiny 2020-05-07
doomvsjing 2020-05-07
hqulyc 2020-05-05
lyccsu 2020-04-30