为什么removeOnGlobalLayoutListener会抛出NoSuchMethodError?

43

我有一些代码,使用ViewTreeObserver#removeOnGlobalLayoutListener(...)编译成功,但运行时此方法会抛出NoSuchMethodError。为什么?


1
我知道答案,只是想以流行和充满活力的问答格式发布 :) - Andrew Wyld
我猜你只是想得到一些赞,但你可以通过给@azertiti正确的答案来挽回自己的形象 :) - Rigotti
@Rigotti,实际上我想指出在Android中有两种功能几乎相同名称相似的方法,因为如果您尝试使用其中一种方法并且由于某种原因它无法正常工作,那么这似乎是一个有用的事情。但是感谢您对我的动机进行了愤世嫉俗的解释! - Andrew Wyld
1
http://meta.stackexchange.com/a/17467 - Andrew Wyld
3个回答

150

ViewTreeObserver中有两个方法名几乎相同。

removeOnGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener victim)

(先onglobal)是在API 16中添加的方法。它替换了

removeGlobalOnLayoutListener(ViewTreeObserver.OnGlobalLayoutListener victim)

(先globalon),后者自API 1以来一直存在,但现在已被弃用。

这两种方法都可以在编译时出现(如果您正在构建Jellybean或更高版本),但新版本将无法在Jellybean之前的设备上运行。

以下代码可以避免错误:

try {
    thing.removeOnGlobalLayoutListener(victim);
} catch (NoSuchMethodError x) {
    thing.removeGlobalOnLayoutListener(victim);
}

所以这段代码:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
    thing.removeGlobalOnLayoutListener(victim);
} else {
    thing.removeOnGlobalLayoutListener(victim);
}

感谢您分享您的问题和解决方案。我尝试了您的代码,但仍然遇到问题。您能否看一下我的问题,链接为http://stackoverflow.com/questions/18285540/stop-listening-for-more-listener-events? - Geek
25
哇,这就像谷歌在挑逗开发者。感谢这个解决方案! - Elad Avron
3
哈,我明白你的意思!我认为这是为了与 ViewTreeObserver#addOnGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener) 保持一致,而在 Android 1.5 中有人犯了一个错误,直到 Android 4 才有人注意到并修复了它.... - Andrew Wyld

4

我猜你在谈论ViewTreeObserver类中的removeOnGlobalLayoutListener方法。该方法是在API 16级别中添加的。我最好的猜测是你试图在运行旧版本Android系统的设备上使用它,因此找不到该方法。


我知道,我刚刚发现这个并且认为告诉大家removeGlobalOnLayoutListener(...)(已弃用,API 1)是值得的 :) - Andrew Wyld

3
我有可用的代码。
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
    if (Build.VERSION.SDK_INT < 16) {
        v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
    } else {
        v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接