Android 调用ViewGroup#addView和ViewGroup#removeView会导致NullPointerException

Android 调用ViewGroup#addView和ViewGroup#removeView会导致NullPointerException,android,android-view,android-framelayout,Android,Android View,Android Framelayout,在方法内部,我调用并如下所示: public class EnclosingClass extends FrameLayout { ... void fooMethod() { ... viewGroup1.addView(this); viewGroup2.removeView(this); ... } ... } void fooMethod() { ... new Handle

在方法内部,我调用并如下所示:

public class EnclosingClass extends FrameLayout {
    ...
    void fooMethod() {
        ...
        viewGroup1.addView(this);
        viewGroup2.removeView(this);
        ...
    }
    ...
}
void fooMethod() {
    ...
    new Handler().post(new Runnable() {
        @Override
        public void run() {
            viewGroup1.addView(EnclosingClass.this);
            viewGroup2.removeView(EnclosingClass.this);
    });
    ...
}
这在纵向模式下可以正常工作(调用多次都没有任何问题),但只要我将屏幕方向更改为横向,我就会得到一个
NullPointerException
:(仅供参考,
fooMethod
在方向更改期间被调用):

为了解决这个问题,我将
addView
removeView
放在
Runnable
中,如下所示:

public class EnclosingClass extends FrameLayout {
    ...
    void fooMethod() {
        ...
        viewGroup1.addView(this);
        viewGroup2.removeView(this);
        ...
    }
    ...
}
void fooMethod() {
    ...
    new Handler().post(new Runnable() {
        @Override
        public void run() {
            viewGroup1.addView(EnclosingClass.this);
            viewGroup2.removeView(EnclosingClass.this);
    });
    ...
}
这确实解决了问题,一切似乎都很好,但我不明白为什么。将这些方法放在消息队列中如何帮助解决这个问题?另外,为什么我在堆栈跟踪中看不到对我的代码的任何引用?我通过逐渐注释代码发现了问题

public final void runOnUiThread(Runnable action) {
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(action);
    } else {
        action.run();
    }`enter code here`
}
因为您在真正的UIThread上使用runOnUiThread,所以代码在else分支上运行:action.run(),这是一个串行操作。如果其他api仍然在具有本地mChildCount的UI线程上运行,则将遇到空指针,(UI线程不安全)