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;
}