您的位置:首页 > 移动开发

packageName和applicationId有什么区别(基于最新官方文档)

2017-01-16 22:28 525 查看
一.背景

因为一些软件需要配置不同平台,要求“包名”(实际上指的是applicationId)不一样,然后我就想为什么只要改applicationId,不改packageName,而且这两者有什么区别呢?所以就有了今天的这篇博客了


二.官方文档

啥都不如直接看官方文档来的快,接下来我就翻译下吧,就当练手了,老司机可以直接看官方文档


官方文档:
https://developer.android.com/studio/build/application-id.html
Every Android app has a unique application ID that looks like a Java package name, such as com.example.myapp. This ID uniquely identifies your app on the device and in Google Play Store.
If you want to upload a new version of your app, the application ID (and the certificate you sign it
with) must be the same as the original APK—if you change the application ID, Google Play Store treats the APK as a completely different app. So once you publish your app, you should never change the application ID.
Your application ID is defined with the
applicationId
property in your module's
build.gradle
file, as shown here:

android {
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
...
}


翻译:

每个app都有一个唯一一个applicationId,看起来有点像包名,例如com.example.myapp.这个Id用于android设备和GooglePlay上识别app的唯一性。如果你想上传一个新版本的app,applicationId(还有签名)必须跟之前的app保持一致,如果你改变了applicationId,Google Play 会认为这是两个完全不同的app(不仅仅是版本不同而已),所以,一旦你发布了app,这个applicationId就永远不能改了。

When you create a new project in Android Studio, the
applicationId
exactly matches the Java-style package name you chose during setup. However, the application ID and package name are independent of each other beyond this point. You can
change your code's package name (your code namespace) and it will not affect the application ID, and vice versa (though, again, you should not change your application ID once you publish your app). However, changing the package name has other consequences
you should be aware of, so see the section about modifying the package name.

And although the application ID looks like a traditional Java package name, the naming rules for the application ID are a bit more restrictive:

It must have at least two segments (one or more dots).
Each segment must start with a letter.
All characters must be alphanumeric or an underscore [a-zA-Z0-9_].

翻译:

当你创建了一个新工程,这个applicationId会跟你设置的java风格的包名保持一致,然而除了这个,applicationId和包名是完全独立的,你可以改变代码的包名(你的代码命名空间)而且这不会影响applicationId,反过来也一样(再次强调,一旦发布了app,这个app的applicationId就不应该改变了),然而改变包名会有其他影响,看这个modifying
the package name.
尽快applicationId跟包名差不多,但是他的命名会有一些限制

1.必须有两个片段(也就是至少要一个 . (点) )

2.每个片段都必须要字母开头

3.所有字母数字和下划线必须在[a-ZA-Z0-9]这个范围内

Note: The application ID used to be directly tied to your code's package name; so some Android APIs use the term "package name" in their method names and parameter names, but this is actually your application ID. For example, the
Context.getPackageName()
method
returns your application ID. There's no need to ever share your code's true package name outside your app code.

Caution: If you are using
WebView
, consider using your
package name as a prefix in your application ID; otherwise you might encounter problems as described in issue
211768.

翻译:

注意:applicationId过去直接绑定包名,所以有些androird API 用"package name"这个术语在方法名和参数名上,但是事实上指的是applicationId,例如context.getPackageName()返回的就是applicationId
,没有必要再app代码中展示真的包名。

小心:

如果你用了webView,在applicationId注意要用packageName作为前缀,否则就会遇到21178这个问题。

Change the application ID for build variants

When you build an APK for your app, the build tools tag the APK with the application ID defined in the
defaultConfig
block from the
build.gradle
file (as shown below). However, if you want to create different versions
of your app to appear as separate listings on Google Play Store, such as a "free" and "pro" version, you need to create separate build
variants that each have a different application ID.

In this case, each build variant should be defined as a separate product flavor.
For each flavor inside the
productFlavors {}
block, you can redefine the
applicationId
property, or you can instead append a segment to the default application ID using
applicationIdSuffix
,
as shown here:
android {
defaultConfig {
applicationId "com.example.myapp"
}
productFlavors {
free {
applicationIdSuffix ".free"
}
pro {
applicationIdSuffix ".pro"
}
}
}


This way, the application ID for the "free" product flavor is "com.example.myapp.free".

You can also use
applicationIdSuffix
to append a segment based on your build
type, as shown here:
android {
...
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
}

当你构建app,build tool 会把build.gradle中的defaultConfig定义的applicationId给APK打tag,然而,如果你想要创造“同一个”app不同的版本同时在google Play上展示的话,例如下面的free 和 pro ,你需要分别给他们不同的applicationId

在这种情况下,build variant 需要定义成 product flavor中的不同区块,productFlavors 中的每个flavor ,你可以定义applicationID属性,或者只是像下面一样加个后缀名。

这样的话,free的applicationID 就是com.example.myapp.free

你也可以用applicationIdSuffix像下面一样添加一个后缀

Because Gradle applies the build type configuration after the product flavor, the application ID for the "free debug" build variant is now "com.example.myapp.free.debug". This is useful when you want to have both the debug and the release build on the same
device, because no two APKs can have the same application ID.

Remember that APKs with different application IDs are treated as different apps in Google Play Store. So if you instead want to use the same app listing to distribute multiple APKs that each target a different device configuration (such as the API level), then
you must use the same application ID for each build variant but give each APK a different
versionCode
. For more information, read about Multiple
APK Support.

Caution: For compatibility with previous SDK tools, if you do not define the
applicationId
property in your
build.gradle
file, the build tools use the package name from the
AndroidManifest.xml
file
as the application ID. In that case, refactoring your package name also changes your application ID.

Tip: If you need to reference the application ID in your manifest file, you can use the
${applicationId}
placeholder in any manifest attribute. During a build, Gradle resplaces this tag with the actual application ID.
For more information, see Inject Build Variables into the Manifest.
翻译:

因为Gradle是在product flavor应用build Type的设置,所以 free debug 的applicationId现在是 com.example.myapp.free.debug,在你想要在同一个设备上既有debug和release版本的时候这个很有用,因为完全一样的app必须有同一个applicationID

记住google play具有不同的applicationId的APK就是完全不同的app,所以如果你反而想要用一个app展示不同的APK,这些apk每个设备的配置都不一样(例如API level),所有你必须用用同一个applicationId,然后versionCode不一样就行了,想要知道更多就看 Multiple APK Support

小心:

为了兼容之前的SDK tools,如果你在build.gradle中没有定义applicationID这个属性的话,build tools会用AndroidMainfest.xml中的package name当做applicationId,在那种情况下,改了包名就会改变applicationId

建议:

如果你要在清单文件中引用applicationID,你可以用${applicationId}占位符,在编译的时候,Gradle会这个替换成真正的applicationId,想要知道更多Inject
Build Variables into the Manifest

Change the application ID for testing

By default, the build tools apply an application ID to your instrumentation
test APK using the application ID for the given build variant, appended with
.test
. For example, a test APK for the
com.example.myapp.free
build variant has the application ID
com.example.myapp.free.test
.

Although it shouldn't be necessary, you can change the application ID by defining the
testApplicationId
property in your
defaultConfig
or
productFlavor
block.
Note: To avoid name collisions with the app under test, the build tools generate the
R
class for your test APK with a namespace based on the test application ID, instead of the package name defined in the manifest file.
翻译:

默认build tools会给instruction test APK的build variant 应用尾部添加了.test的applicationId,例如一个初始applicationId是com.example.myapp.free的test APK 的build variant 最后的applicationId是com.example.myapp.free.test.

你可以通过改变testApplicationId这个属性(在defaultConfig和productFlavor中),尽快这是没必要的

注意:为了避免和测试下的app混淆,build tool 给你的test APK生成了R class文件,这个文件的命名空间是test ApplicationID,而不是清单文件中的包名(packageName)

Change the package name

Although your project's package name matches the application ID by default, you can change it. However, if you want to change your package name, be aware that the package name (as defined by your project directory structure) should always match the
package
attribute
in the
AndroidManifest.xml
file, as shown here:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp"
android:versionCode="1"
android:versionName="1.0" >


The Android build tools use the
package
attribute for two things:

It applies this name as the namespace for your app's generated
R.java
class.
Example: With the above manifest, the
R
class will be
com.example.myapp.R
.

It uses it to resolve any relative class names that are declared in the manifest file.
Example: With the above manifest, an activity declared as
<activity android:name=".MainActivity">
is resolved to be
com.example.myapp.MainActivity
.

As such, the name in the
package
attribute should always match your project's base package name where you keep your activities and other app code. Of course, you can have sub-packages in your project, but then those files must import the
R.java
class
using the namespace from the
package
attribute, and any app components declared in the manifest must add the missing sub-package names (or use fully-qualified package names).

If you want to refactor your package name completely, be sure you update the
package
attribute as well. As long as you use Android Studio's tools to rename and refactor your packages, then these automatically stay in sync. (If they don't
stay in sync, your app code can't resolve the
R
class because it's no longer in the same package, and the manifest won't identify your activities or other components.)

You must always specify the
package
attribute in your project's main
AndroidManifest.xml
file. If you have additional manifest files (such as for a product flavor or build type), be aware that the package name supplied
by the highest-priority manifest file is always used in the final merged manifest. For more information, see Merge
Multiple Manifest Files.

One more thing to know: Although you may have a different name for the manifest
package
and the Gradle
applicationId
, the build tools copy the application ID into your APK's final manifest file at
the end of the build. So if you inspect your
AndroidManifest.xml
file after a build, don't be surprised that the
package
attribute has changed. The
package
attribute is where Google Play Store
and the Android platform actually look to identify your app; so once the build has made use of the original value (to namespace the
R
class and resolve manifest class names), it discards that value and replaces it with the application
ID.

翻译:

尽管默认包名(packageName)和applicationID是一样的,但是你可以打破这种关系。然后,如果你想要改变你的包名,那你要明白,包名(定义在工程目录结构中)应该跟清单文件一样(说白了就是工程目录包名要跟清单文件中定义的一样)

Android build tools 用package 属性是为了两个东西:

1.为了给自动生成的R.java.class一个命名空间,例如:在上面的清单文件中可以看到,R class文件回事com.example.myapp.R

2.用来分解定义在清单文件中的声明的一些相关的类,例如:在上面的清单文件中可以看到,一个activity声明

为<activity android:name=".MainActivity">可以被分解成com.example.myapp.MainActivity.

就像那样,在package属性的值应该和保存代码的工程目录一样,当然,你可以在工程里有子目录,但是那些R.java文件必须用pack属性作为命名控件,而且任何定义在app的元素都必须加上省略的子目录名(或者用完整的包名)

如果你想要重新完全的改变packageName,一定要记得你也改变了package属性.只要你用了Android studio tools去改变你的包名,那么它们会自动同步(如果它们没有自动同步,你的app code不能识别R class文件,因为它们不再是在一个包之下,而且清单文件也不能识别你的activity和其他元素)

你必须在清单文件中指定package这个属性.如果你另外还有清单文件(例如为了 product flavor 或者build type),要明白!优先级最高的清单文件提供的package name一直会被被用在最后合并的清单文件,详情Merge Multiple 清单文件

更多知识:尽管application和packageName可能不一样,但是build tools 会在build结束的时候把applicationId 拷贝到你的app最终的清单文件中,所以你如在build之后检查清单文件,不用对packageName改变了感到奇怪,package属性 是Google Play 和android平台识别唯一app的党法,所以只要build只要build用了原始的值(R class的命名控件来分别清单文件的class name),最后会用applicationId替代。

最终我总结一下:

package用于资源文件(R class)的命名控件和清单文件声明一些元素,applicationId是google play(国内应用市场估计也是) 和android平台识别唯一app的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: