清单中的 Android 包和您使用的类的 Java 包是不同的概念。为方便起见,默认情况下它们碰巧是相同的。但是,它们可以完全不同且不相关。
当你声明你的activity、services、content provider和broadcast listener时,你可以通过以下三种方式指定组件类名(假设你的Android包是org.example.myapp
)
- 类名,即
MyActivity
. 操作系统将假定您的类位于与您的 Android 包同名的 Java 包中,并将其解析为完全限定的类名org.example.myapp.MyActivity
. 请注意,这种形式等价于.MainActivity
,它是...
- 相对类名,即
.ui.MyActivity
. 操作系统将假定您的类位于 Java 包中,该包位于与您的 Android 包同名的 Java 包中,并将其解析为完全限定的类名org.example.myapp.ui.MyActivity
. 注意前导.
,很重要!否则你会落入...
- 完全合格,即
com.android.example.myapp.MyActivity
。操作系统将使用它作为它需要加载的类的确切名称,并将忽略 Android 包名称。
Android 包名和 Java 包名之间的混淆是由于对两个独立的概念使用相同的术语。的文档ComponentName
并没有使它变得更容易,因为它调用了它的两个组件package
and class
,而它们实际上是Android package
and Java class
(上面三个变体中的任何一个都可以接受)。
有了更长的序言,您的问题的答案很简单:
您不能在清单中声明多个包。但是,您也不需要这样做。就操作系统而言,Android 包名称实际上就是您的应用程序的标识,仅此而已。您可以在代码中使用任何 Java 包。
警告:
默认情况下,包含所有资源标识符的自动生成R
类是在与您的 Android 包同名的 Java 包中生成的。因此,如果您的 Android 包名和 Java 包名不同,您有两种选择:
R
使用您的 Android 包的名称从 Java 包中显式导入类
- 使用
appt
命令行中的工具和--custom-package
选项将R
文件生成到主 Java 包中。(我链接到 eLinux,因为 Android 文档没有太多关于该工具的内容。但它是 Android SDK 的一部分)
虽然这似乎证明了这两个包名称是相关的,但这只是工具所采用的便利。遗憾的是,虽然该aapt
工具允许为R
类显式设置目标 Java 包,但 Eclipse 和 IntelliJ 都隐藏了该选项,这使得混淆更加彻底。