【问题标题】:Android id collision mechanism for R.javaR.java的Android id冲突机制
【发布时间】:2011-01-07 20:45:19
【问题描述】:

我们都知道在为 Android 生成 id 时使用

@+id/foo

Android 为我们在 R.java 中创建了一个条目,例如:

 public static final class id {
        public static final int foo=0x7f060005;
 }

如果在不同的 xml 文件中(比如说,在两个布局中)存在名称冲突,会发生什么? @+id 机制确保我们在另一个仍然存在的情况下覆盖 id 名称,但是在 R.java 中为我们生成了哪个?

【问题讨论】:

    标签: android collision


    【解决方案1】:

    @+id/foo 语法将在 id 不存在或使用现有 id 时添加。
    当你findViewById时,它会对你调用该方法的视图进行操作。

    因此,如果您有嵌套视图,则每个视图的 id 都是唯一的。 例如View1 -> View2 都有 foo。 View1.findViewById(R.id.foo) 将不同于 View2.findViewById(R.id.foo)

    edit:我想主要要提的是两个布局不能有相同的 id。 有关 id 约束的更多信息:http://d.android.com/guide/topics/ui/declaring-layout.html

    【讨论】:

    • 如果您使用包含,第二点尤其重要,因为重新使用包含包含的相同布局通常会导致视图树的多个分支中使用相同的 ID。
    • 这是否意味着 R.java 仅充当名称容器?如果我在两个具有相同 id 名称的不同 xml 文件中声明两个按钮并尝试在 Activity 中检索它,会发生什么情况?编辑:您刚刚添加的链接让我认为布局也充当其中声明的 id 的“命名空间”。
    • +1 很好。我更新了我的答案,并提供了指向该指南的链接,特别提到了这一点。我认为对于已经习惯于为整个应用程序中的元素(例如网页中的元素)使用唯一 ID 的开发人员(尤其是 Web 开发人员)来说,这可能会有些混乱。
    • @bodom_lx,例如,我认为您不能拥有两个文件:main_layout.xml 和 secondary_layout.xml,两者都带有@+id/layout。我还没有尝试过,但我认为您的应用程序不会编译。
    • @JimSchubert 您能否扩展此答案以解释当一个视图包含另一个视图时 id 冲突会发生什么?它在实践中似乎效果很好,但我不太清楚为什么。
    【解决方案2】:

    我尝试了一个带有以下 xml 的简单 Hello World 应用程序:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
    <TextView
            android:id="@+id/textview"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="text1"
    />
    
    <TextView
            android:id="@+id/textview"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="text2"
    />
    
    </LinearLayout>
    

    我的两个文本视图都有相同的 ID。它编译得很好,运行得很好,同时渲染了两个 TextView,当我执行 findViewByid() 时,第一个被找到,并且我所有的函数调用(如 setText)都应用于它。理想情况下,AAPT 应该抓住这一点,但显然没有。除非程序员依赖 id,否则它不会严重破坏某些东西。所以这就像是在说:如果你傻到写出这样的代码,那么你应该崩溃。

    AAPT 不会太在意它。对它来说,这就像一个简单的视图扩展,程序员没有提供明确的 id。

    【讨论】:

    • 感谢您努力对其进行测试并分享详细信息。
    【解决方案3】:

    我认为它只是重复使用已经生成的标识符。我倾向于重复使用 ID,而且从来没有遇到过问题。

    【讨论】:

    • 它重用它意味着如果存在另一个条目,它会覆盖 R.java 中的条目。 Android 如何在编译时决定保留哪一个和删除哪一个?
    • 这个问题没有意义:如果它们有相同的名称,它们就具有相同的值,反之亦然。 Android 不会“保留”一个或“丢弃”一个。 @+id 创建一个标识符如果它还不存在。
    • 我的问题是由于对 R.java 机制的误解而产生的:我认为 R.java 包含指向 View 对象的“指针”。现在我知道它只是一个标识符容器。因此,@+id 机制现在已经完全符合逻辑了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    相关资源
    最近更新 更多