gpt4 book ai didi

android - 调用 ViewGroup#addView 和 ViewGroup#removeView 导致 NullPointerException

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:26:26 31 4
gpt4 key购买 nike

在方法内部,我调用 addViewremoveView如下:

public class EnclosingClass extends FrameLayout {
...
void fooMethod() {
...
viewGroup1.addView(this);
viewGroup2.removeView(this);
...
}
...
}

这在纵向模式下工作正常(它被多次调用没有任何问题),但是一旦我将屏幕的方向更改为横向,我就会得到一个 NullPointerException:(仅供引用,fooMethod 在方向更改期间从 surfaceChanged 调用):

 18376         AndroidRuntime  E  FATAL EXCEPTION: main
18376 AndroidRuntime E Process: com.google.android.apps.chrome, PID: 18376
18376 AndroidRuntime E java.lang.NullPointerException
18376 AndroidRuntime E at android.widget.FrameLayout.layoutChildren(FrameLayout.java:405)
18376 AndroidRuntime E at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
18376 AndroidRuntime E at android.view.View.layout(View.java:14817)
18376 AndroidRuntime E at android.view.ViewGroup.layout(ViewGroup.java:4631)
18376 AndroidRuntime E at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
18376 AndroidRuntime E at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
18376 AndroidRuntime E at android.view.View.layout(View.java:14817)
18376 AndroidRuntime E at android.view.ViewGroup.layout(ViewGroup.java:4631)
18376 AndroidRuntime E at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
18376 AndroidRuntime E at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
18376 AndroidRuntime E at android.view.View.layout(View.java:14817)
18376 AndroidRuntime E at android.view.ViewGroup.layout(ViewGroup.java:4631)
18376 AndroidRuntime E at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1987)
18376 AndroidRuntime E at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1744)
18376 AndroidRuntime E at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
18376 AndroidRuntime E at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
18376 AndroidRuntime E at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
18376 AndroidRuntime E at android.view.Choreographer.doCallbacks(Choreographer.java:574)
18376 AndroidRuntime E at android.view.Choreographer.doFrame(Choreographer.java:544)
18376 AndroidRuntime E at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
18376 AndroidRuntime E at android.os.Handler.handleCallback(Handler.java:733)
18376 AndroidRuntime E at android.os.Handler.dispatchMessage(Handler.java:95)
18376 AndroidRuntime E at android.os.Looper.loop(Looper.java:136)
18376 AndroidRuntime E at android.app.ActivityThread.main(ActivityThread.java:5017)
18376 AndroidRuntime E at java.lang.reflect.Method.invokeNative(Native Method)
18376 AndroidRuntime E at java.lang.reflect.Method.invoke(Method.java:515)
18376 AndroidRuntime E at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
18376 AndroidRuntime E at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
18376 AndroidRuntime E at dalvik.system.NativeStart.main(Native Method)

为了解决这个问题,我把addViewremoveView放在一个Runnable里面,如下:

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 线程上运行,则会遇到 NULL 指针,(UI线程不安全)

关于android - 调用 ViewGroup#addView 和 ViewGroup#removeView 导致 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21864041/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com