我正在查看Android 4.2中引入的新API。在查看UserManager类时,我遇到了以下方法:

公共布尔值isUserAGoat()用于确定拨打此呼叫的用户是否需要进行远程传送。返回进行此调用的用户是否为山羊。

该如何使用以及何时使用?


Android R更新:

在Android R中,此方法始终返回false。谷歌表示,这样做是为了“保护山羊隐私”:

/**
 * Used to determine whether the user making this call is subject to
 * teleportations.
 *
 * <p>As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method can
 * now automatically identify goats using advanced goat recognition technology.</p>
 *
 * <p>As of {@link android.os.Build.VERSION_CODES#R}, this method always returns
 * {@code false} in order to protect goat privacy.</p>
 *
 * @return Returns whether the user making this call is a goat.
 */
public boolean isUserAGoat() {
    if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
        return false;
    }
    return mContext.getPackageManager()
            .isPackageAvailable("com.coffeestainstudios.goatsimulator");
}

上一个答案:

从他们的源代码来看,该方法在API 21中更改之前一直返回false。

/**
 * Used to determine whether the user making this call is subject to
 * teleportations.
 * @return whether the user making this call is a goat 
 */
public boolean isUserAGoat() {
    return false;
}

作为开发人员,该方法似乎对我们没有实际用处。之前有人说过这可能是一个复活节彩蛋。

在API 21中,实现被更改为检查是否安装了带有com.coffeestainstudios.goatsimulator包的应用程序

/**
 * Used to determine whether the user making this call is subject to
 * teleportations.
 *
 * <p>As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method can
 * now automatically identify goats using advanced goat recognition technology.</p>
 *
 * @return Returns true if the user making this call is a goat.
 */
public boolean isUserAGoat() {
    return mContext.getPackageManager()
            .isPackageAvailable("com.coffeestainstudios.goatsimulator");
}

这是来源和变化。


这似乎是谷歌内部的一个笑话。谷歌Chrome任务管理器中也有此功能。除了一些工程师觉得它很有趣之外,它没有任何用途。这本身就是一个目的,如果你愿意的话。

在Chrome中,用Shift+Esc键打开任务管理器。右键单击以添加Goats Teleported列。想知道

甚至有一个巨大的铬虫报告说,有太多的被传送的山羊。

以下Chromium源代码片段是从HN注释中窃取的。

int TaskManagerModel::GetGoatsTeleported(int index) const {
  int seed = goat_salt_ * (index + 1);
  return (seed >> 16) & 255;
}

我不知道这是否是“官方”用例,但以下内容在Java中产生了一个警告(如果与返回语句混合,会进一步产生编译错误,导致无法访问代码):

while (1 == 2) { // Note that "if" is treated differently
    System.out.println("Unreachable code");
}

但这是合法的:

while (isUserAGoat()) {
    System.out.println("Unreachable but determined at runtime, not at compile time");
}

因此,我经常发现自己编写了一个愚蠢的实用程序方法,以最快的方式虚设一个代码块,然后在完成调试时找到对它的所有调用,因此只要实现不改变,就可以使用它。

JLS指出,如果(false)没有触发“不可访问的代码”,因为这会破坏对调试标志的支持,即基本上是这个用例(h/t@auselen)。(例如,静态最终布尔值DEBUG=false)。

我用if替换了while,产生了一个更模糊的用例。我相信你可以像Eclipse一样,用这种行为来破坏你的IDE,但这种编辑是在4年后的将来,我没有一个Eclipse环境可以玩。


在每个版本的Android中都有一个有趣的命名方法/常量/whatever。

我所见过的唯一实际用途是在谷歌I/O大赛的最后一场比赛中,他们询问了特定版本的应用程序,看看参赛者是否阅读了每个版本的API差异报告。比赛也有编程问题,但一般来说,一些琐事可以先自动评分,以便将提交的数量降至更容易检查的合理数量。


谷歌非常喜欢山羊和山羊复活节彩蛋。之前甚至有关于它的Stack Overflow帖子。

如前几篇文章所述,它也存在于Chrome任务管理器中(2009年首次出现在野外):

<message name="IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN" desc="The goats teleported column">
    Goats Teleported
</message>

然后在2010年初的Windows、Linux和Mac版本的Chrome中)。“Goats Teleported”的数量实际上是随机的:

 int TaskManagerModel::GetGoatsTeleported(int index) const {
     int seed = goat_salt_ * (index + 1);
     return (seed >> 16) & 255;
 }

谷歌对山羊的其他引用包括:

用山羊割草山羊是baaaahk

据我所知,山羊和谷歌最早的关联是在最初的“用山羊割草”博客文章中。

我们可以放心地假设,它只是一个复活节彩蛋,除了返回错误之外,没有任何实际用途。


有一个类似的调用isUserAMonkey(),如果正在使用MonkeyRunner工具,则返回true。SDK的解释和这个一样奇怪。

公共静态布尔值isUserAMonkey(){}如果用户界面当前被猴子搞乱,则返回true。

这是来源。

我预计,这是在一个名为something with a goat的新SDK工具的预期中添加的,它将实际用于测试该工具的存在。

另请参阅一个类似的问题,ActivityManager:isUserAMonkey中的奇怪函数。这意味着什么,它的用途是什么?。


作为对@djechlin答案的补充(顺便说一句,这是一个好答案!),当您想在某个特定的迭代或特定的递归调用中停止时,此函数调用也可以用作虚拟代码,以在IDE中保存断点,例如:

可以使用isUserAGoat()代替虚拟变量声明,该声明将在IDE中显示为警告,并且在Eclipse的特定情况下,将阻塞断点标记,使其难以启用/禁用。如果该方法用作约定,则所有调用都可以稍后由某个脚本过滤(可能在提交阶段?)。

谷歌是重度Eclipse用户(他们提供了几个Eclipse插件项目:Android SDK、GAE等),所以@djechlin的回答和这个补充答案很有意义(至少对我来说)。


在语音识别领域,用户分为山羊和绵羊。

例如,第89页:

绵羊是语音识别效果特别好的人,山羊是语音识别性能特别差的人。只有语音识别器知道它们之间的区别。人们无法预测谁的声音容易被识别,谁的声音不会被识别。最好的策略是设计界面,使其能够处理各种环境中的各种声音

也许,未来计划将Android用户标记为山羊,以便能够根据山羊的需要配置语音识别引擎


有趣的复活节彩蛋。在Ubuntu版本的Chrome中,在任务管理器(shift+esc)中,右键单击可以添加一个科幻专栏,在意大利语版本中为“Capre Teletransportate”(Teleported Goats)。

这里有一个有趣的理论。


从API 21(第一个Android 5.0/棒棒糖SDK)开始,这将检测山羊模拟器应用程序是否已安装:

/**
 * Used to determine whether the user making this call is subject to
 * teleportations.
 *
 * <p>As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method can
 * now automatically identify goats using advanced goat recognition technology.</p>
 *
 * @return Returns true if the user making this call is a goat.
 */
public boolean isUserAGoat() {
    return mContext.getPackageManager()
            .isPackageAvailable("com.coffeestainstudios.goatsimulator");
}

这应该清楚地表明,如果(错误),djechlin将其用作无警告的建议是一种潜在的灾难性策略。以前为每个设备返回的错误现在返回了一个看似随机的值:如果这个值在代码中埋得足够深,那么可能需要很长时间才能弄清楚新的bug来自何处。

一句话:如果你不控制一个方法的实现,并决定将其用于API文档中所述以外的目的,那么你就会遇到麻烦。


这不是内部笑话

显然它只是一个应用程序检查器山羊模拟器-咖啡色工作室

如果你安装了山羊模拟器,你就是一只山羊。如果你没有安装,你就不是山羊。

我想这更多是一个开发者的个人实验,最有可能找到有共同兴趣的人。


从可用性和可访问性的角度来看,了解您的用户是否是山羊很重要。

如果山羊想要真正受益于信息时代所提供的一切,那么它们的需求与软件的需求其实是截然不同的。

我觉得很好,一些好心的开发者关心我们所有的用户,而不仅仅是那些时尚的用户。