gpt4 book ai didi

java - 实用程序类的静态成员(null)生命周期

转载 作者:行者123 更新时间:2023-12-02 11:47:40 28 4
gpt4 key购买 nike

我有一个具有常量和静态方法的实用程序类。此外,它还有一个静态字段。

public class MyUtil implements IMyUtil {
public static String IS_DEBUG = false;
...
private static MyEnumType mMyEnum;

...
// static getter setter methods for mMyEnum
}

我有两个 fragment (为了简单起见,FragmentAFragmentB)。FragmentA 设置 mMyEnum 值,然后将其与 getter 方法一起使用。当用户按下按钮时,我会显示 FragmentB。在 FragmentB 的 onActiviyCreated() 方法中,我获取了 mMyEnum 值。

在我的测试设备上一切正常。但在 Google Play Console 中,我在这一行看到一堆 NullPointerException 错误:

String testString = MyUtil.getMyEnum().getSomeStringValue();

我不明白为什么该行上的 myEnum 为 null 以及为什么我无法重现它。 MyUtil显然不能为null,getSomeStringValue()可以为null,但它不会抛出NullPointerException,所以只有myEnum可以为null。但为什么?如果它可以为空我该如何重现它?

谢谢。

更新#1:Play 显示了各种设备(三星 A3、S6、S7、S8、LG X、G3、华为 P9 等)和 API 版本(5.0 -> 7.1)。完整的堆栈跟踪是:

java.lang.RuntimeException: 
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2984)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14 (ActivityThread.java)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1642)
at android.os.Handler.dispatchMessage (Handler.java:102)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:6776)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1386)
Caused by: java.lang.NullPointerException:
at com.mycompany.fragment.FragmentB.onActivityCreated (FragmentB.java:35)
at android.support.v4.app.Fragment.performActivityCreated (Fragment.java:2089)
at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManagerImpl.java:1133)
at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManagerImpl.java:1290)
at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManagerImpl.java:1272)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated (FragmentManagerImpl.java:2149)
at android.support.v4.app.FragmentController.dispatchActivityCreated (FragmentController.java:201)
at android.support.v4.app.FragmentActivity.onStart (FragmentActivity.java:600)
at android.support.v7.app.AppCompatActivity.onStart (AppCompatActivity.java:178)
at android.app.Instrumentation.callActivityOnStart (Instrumentation.java:1256)
at android.app.Activity.performStart (Activity.java:6972)
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2937)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14 (ActivityThread.java)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1642)
at android.os.Handler.dispatchMessage (Handler.java:102)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:6776)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1386)

最佳答案

长期存在的静态成员会出现问题,因为 Android 可能会释放内存并在某个时间删除该值(当没有 fragment 处于 Activity 状态并引用它时)。您还没有明确说明是否可以在不先从 FragmentA 设置值的情况下访问 FragmentB,所以这也可能是您的问题。

附加说明 - 常量应该是常量 - 因此应该有 final 关键字。

我建议的解决方案是摆脱这种糟糕的架构,其中两个组件依赖外部上帝对象来维护其状态。将您的枚举值作为 Intent 中的 Extra 传递。

您可以使用以下方式写入 bundle

public static final String KEY_ENUM = "MyEnumKey";

bundle.putString(KEY_ENUM, myEnum.name()):

然后用

读回来
Bundle bundle = intent.getExtras();
MyEnumTypemyEnum = MyEnumType.valueOf(bundle.getString(FragmentA.KEY_ENUM));

另一个建议是确保 myEnum 永远不为空(默认情况下为空)。声明如下:

private static MyEnumType mMyEnum = MyEnumType.MY_DEFAULT_VALUE;

关于java - 实用程序类的静态成员(null)生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48092863/

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