2013-04-17 157 views
0

有时我收到由谷歌随机NullPointerExceptions(见上文)导致的崩溃报告。我试图重现这些错误,但我无法赶上它们。 NPE的Android - 随机NullPointerException崩溃报告

例子,我得到:

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

Caused by: java.lang.NullPointerException 
at com.gamequiz.databasemanager.QuestionManager.getQuestionsFromLevel(QuestionManager.java:30) 
at com.gamequiz.databasemanager.QuestionManager.getNumberOfQuestionAnsweredFromLevel(QuestionManager.java:148) 


不过,我觉得,我的 dbHelper变量是 null有时,但我想不出为什么。

因为我不知道如何解决,我张贴我的代码的所有步骤:

首先我初始化在LaunchActivity所有经理:

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

     initializeAllManagers(); 

     //some stuff 

} 

public void initializeAllManagers(){ 
     InitializeAllManagers.init(getApplicationContext()); 
    } 

在我InitializeAllManagers类,我将所有的管理人员,我需要为应用程序的生命周期:

public class InitializeAllManagers { 

    public static void init(Context context){ 
     DatabaseManager.init(context); 
     CategoryManager.init(DatabaseManager.getInstance().getHelper()); 
     //and others initializations 
    } 
} 

DatabaseManager类(dbManager的初始化d dbHelper):

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

所以我怀疑我dbHelper变量是null有时。有没有人有关于我如何解决这个问题的想法?

编辑:

NPE主要是指这行:

cList = (ArrayList<Category>) dbHelper.getCategoryDao().queryForAll(); 
Dao <Question, Long> questionDao = dbHelper.getQuestionDao(); 

这就是为什么我怀疑dbHelpernull有时,显然崩溃时,应用程序是睡了一会发生(见上面的反馈)。一个用户的


反馈:

左右,主要是如果我离开应用程序而不退出它,应用程序会经常崩溃 当我尝试回去吧。有时我只是被送回 的菜单,但大多只是一路走出应用程序,我必须 重新启动它才能继续。

+0

任何想法具体行号对应NPE? – Gray

+0

'dbHelper'可以是'null',或'getCategoryDao()'返回的dao可以是'null'。你可以显示该代码吗? – Gray

+0

有没有办法帮助者可以被分配到'null'?那可以改成'最后'吗? – Gray

回答

0

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

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

public static DatabaseManager getInstance() { 
    if(instance == null) instance = new DatabaseManager(); 
    return instance; 
} 

编辑:
请注意,我在这个答案的推理是错误的。请阅读所有意见以进行澄清。

+0

尊重,绝对废话。 Android只会删除垃圾收集对象。它不会“感觉像去除”任何东西。它可能会破坏您的活动,如通过应用程序生命周期记录和控制的那样。当您的应用程序返回前台时,活动将被重新创建,当然,它声明的任何变量将被重新初始化,这是onPause()和onResume()的目的,具有处理保存和恢复状态的多种方式。 “特别是静态变量可以被删除”。咦?你在谈论单身吗?应用程序类字段? – Simon

+0

我的意思是每个静态变量,包括单身(当然不是常量)。当Android需要内存时,它可以选择从堆中移除东西,例如可以移除一个ClassLoader实例。如果这是加载包含您的静态变量的Class的ClassLoader,则该类也将被删除。这个Activity可能不会受到影响,因为它是由另一个ClassLoader加载的。所以,活动仍然在这里,但你的另一个类中的静态变量可能不是。我有一个与随机NPE类似的问题,这解决了它。 – SimonSays

+0

再次,没有它不。只有3种方法可以从堆中移除任何东西。 1.一个对象,它的作用域是一个封闭的Activity,并且该Activity被破坏。 2.引用计数为零的堆对象。 3.应用程序被破坏。没有任何东西仍然在范围内被删除。如果是这样,Android的土地会出现混乱。何时收集堆对象是完全可以确定的。 – Simon