Java Android-随机NullPointerException崩溃报告

Java Android-随机NullPointerException崩溃报告,java,android,nullpointerexception,ormlite,Java,Android,Nullpointerexception,Ormlite,有时我会收到来自谷歌的崩溃报告,这些报告是由随机NullPointerExceptions(见上文)引起的。我试图重现那些错误,但没能抓住它们 我得到的NPE示例: Caused by: java.lang.NullPointerException at com.gamequiz.databasemanager.CategoryManager.getAllCategories(CategoryManager.java:28) 我认为我的dbHelper变量有时是null,但我不明白为什么

有时我会收到来自谷歌的崩溃报告,这些报告是由随机
NullPointerExceptions
(见上文)引起的。我试图重现那些错误,但没能抓住它们

我得到的NPE示例:

Caused by: java.lang.NullPointerException
at com.gamequiz.databasemanager.CategoryManager.getAllCategories(CategoryManager.java:28)


我认为我的
dbHelper
变量有时是
null
,但我不明白为什么

由于我不知道如何解决这个问题,我发布了代码的所有步骤:

首先,我初始化
启动活动
中的所有管理器:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_launch);

        initializeAllManagers();

       //some stuff

}

public void initializeAllManagers(){
        InitializeAllManagers.init(getApplicationContext());
    }
在我的
InitializeAllManager
类中,我设置了应用程序生命周期所需的所有管理器:

public class InitializeAllManagers {

    public static void init(Context context){
        DatabaseManager.init(context);
        CategoryManager.init(DatabaseManager.getInstance().getHelper());
        //and others initializations
    }
}
DatabaseManager
类(dbManager和dbHelper的初始化):

最后是一个经理的例子:

public class CategoryManager {

    private static DatabaseHelper dbHelper;

    public static void init(DatabaseHelper dbHelperInstance) {
        dbHelper = dbHelperInstance;
    }

    public static ArrayList <Category> getAllCategories(){
            ArrayList <Category> cList = null;
            try {
                cList = (ArrayList<Category>) dbHelper.getCategoryDao().queryForAll();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return cList;
    }
}
这就是为什么我怀疑
dbHelper
有时是
null
的原因,显然在应用程序睡眠片刻时会发生崩溃(参见上面的反馈)


一个用户的反馈:

因此,如果我离开应用程序而不退出,应用程序通常会 当我试图回到它的时候崩溃了。有时我只是被送回学校 菜单,但大部分都是应用程序之外的,我必须 重新启动以继续


我怀疑当应用程序最小化一段时间,然后重新打开时会发生这种情况。如果Android感觉需要内存,它可以并且将从堆中删除对象。特别是可以删除静态变量。在访问静态变量之前,请检查它们是否为null

例如,在
DatabaseManager
类中,在
getInstance()
方法中而不是在
init()
中创建实例

编辑:

请注意,我在这个答案中的推理是错误的。请阅读所有评论以澄清。

请尊重,绝对是胡说八道。Android仅在对象被垃圾收集时才会删除它们。它不想“移除”任何东西。它可能会破坏应用程序生命周期中记录和控制的活动。当您的应用程序返回前台时,活动将被重新创建,当然,它声明的任何变量都将被重新初始化,这是onPause()和onResume()的目的,有许多处理保存和恢复状态的方法。“尤其是静态变量可以删除”。嗯?你是说单身汉吗?应用程序类字段?我是指每个静态变量,包括单例(当然不是常量)。当Android需要内存时,它可以选择从堆中删除内容,例如,它可以删除ClassLoader实例。如果这是加载包含静态变量的类的类加载器,那么这个类加载器也将被删除。该活动可能不受此影响,因为它是由另一个类加载器加载的。因此,活动仍然在这里,但另一个类中的静态变量可能不在这里。我有一个类似的问题,随机NPE,这修复了它。再次,不,它没有。只有3种方法可以从堆中删除任何内容。1.一个对象,其作用域是一个封闭的活动,该活动将被销毁。2.引用计数为零的堆对象。3.应用程序被销毁。任何仍在范围内的内容都不会被删除。如果是这样的话,安卓的土地将陷入混乱。收集堆对象的时间是完全可以确定的。经过研究,似乎您的观点是正确的,只要进程处于活动状态,静态变量就不会被删除。当Android终止进程并试图在应用程序重新打开时恢复最后一个状态时,会导致NPE问题。例如,如果在SpashScreen中初始化静态变量,则在这种情况下它们将为null。因此,尽管我的推理是错误的,但上面的修复仍然可以解决问题。这是一个关于同一主题的旧讨论。您知道哪些特定行号对应于NPE吗?
dbHelper
可以是
null
,或者
getCategoryDao()
返回的dao可以是
null
。您能显示该代码吗?是否无法将助手分配给
null
?是否可以将其更改为
final
?@灰色问题编辑。您认为在
DatabaseManager
类中将
dbHelper
更改为
final
可以解决这个问题吗?我不是活动生命周期方面的专家。如果应用程序正在休眠片刻,我是否必须在用户重新打开它时强制它重新初始化管理器(这似乎很奇怪)?不@ZouZou,你不应该这样做。我怀疑某些东西没有正确初始化,可能是生命周期的一部分,但启动/销毁是ORMLite内部使用的,所以您应该很好。
public class DatabaseManager {

    private static DatabaseManager instance;
    private DatabaseHelper helper;

    public static void init(Context ctx) {
        if (instance==null) {
            instance = new DatabaseManager(ctx);
        }
    }

    public static DatabaseManager getInstance() {
        return instance;
    }

    private DatabaseManager(Context ctx) {
        helper = new DatabaseHelper(ctx);
    }

    public DatabaseHelper getHelper() {
        return helper;
    }
}
public class CategoryManager {

    private static DatabaseHelper dbHelper;

    public static void init(DatabaseHelper dbHelperInstance) {
        dbHelper = dbHelperInstance;
    }

    public static ArrayList <Category> getAllCategories(){
            ArrayList <Category> cList = null;
            try {
                cList = (ArrayList<Category>) dbHelper.getCategoryDao().queryForAll();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return cList;
    }
}
cList = (ArrayList<Category>) dbHelper.getCategoryDao().queryForAll(); 
Dao <Question, Long> questionDao = dbHelper.getQuestionDao();
public static DatabaseManager getInstance() {
    if(instance == null) instance = new DatabaseManager();
    return instance;
}