create Button 实例在 AnimatorSet.cle 中抛出 NullPointerException



我以编程方式创建按钮时遇到问题。该按钮应该插入到预先存在的布局中。

由于我需要特定容器的尺寸,因此我为该容器创建了一个全局布局侦听器,并在 onGlobalLayout 回调中检查有效大小,然后实例化一个新的按钮。

使用的上下文是容器中的上下文。

final View container = activity.findViewById(...);
container.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    public void onGlobalLayout() {
        if (container.getWidth()>0 && container.getHeight()>0) {
            Button button = new Button(container.getContext());
        }
    }
});

但是,在极少数情况下 - 特别是在从一个活动切换到另一个活动时 - 按钮实例化失败,并在 Android 框架代码中出现 NullPointerException。

java.lang.NullPointerException: Attempt to read from field 'android.animation.Animator android.animation.AnimatorSet$Node.mAnimation' on a null object reference
at android.animation.AnimatorSet.clone(AnimatorSet.java:725)
at android.animation.AnimatorSet.clone(AnimatorSet.java:682)
at android.animation.StateListAnimator.clone(StateListAnimator.java:148)
at android.animation.StateListAnimator$StateListAnimatorConstantState.newInstance(StateListAnimator.java:328)
at android.animation.StateListAnimator$StateListAnimatorConstantState.newInstance(StateListAnimator.java:327)
at android.content.res.ConstantState.newInstance(ConstantState.java:53)
at android.content.res.ConstantState.newInstance(ConstantState.java:61)
at android.content.res.ConfigurationBoundResourceCache.getInstance(ConfigurationBoundResourceCache.java:40)
at android.animation.AnimatorInflater.loadStateListAnimator(AnimatorInflater.java:163)
at android.view.View.<init>(View.java:4815)
at android.widget.TextView.<init>(TextView.java:995)
at android.widget.Button.<init>(Button.java:113)
at android.widget.Button.<init>(Button.java:106)
at android.widget.Button.<init>(Button.java:102)
at android.widget.Button.<init>(Button.java:98)

我的假设是,不知何故上下文不再有效,但我不能把手指放在上面。

当活动被停用时,我会删除侦听器。

有什么想法吗?

正如文档所说 OnGlobalLayoutListener

全局布局状态或视图树中视图的可见性更改时要调用的回调的接口定义。

因此,当 UI 解散时,您正在获得导致 NPE 的"死亡"View。您可以尝试在onStop()中取消注册侦听器以防止这种情况。或者,如果您只需要处理完全创建的View使用

container.post(new Runnable() {
        @Override
        public void run() {
            Button button = new Button(container.getContext());
        }
    });

到目前为止,我找到的唯一解决方案是不通过调用来创建按钮

Button button = new Button(container.getContext());

但是通过创建一个仅包含按钮的小型布局 XML 文件,然后像这样实例化按钮:

LayoutInflater.from(context).inflate(R.layout.button, null)

相关内容

最新更新