getWritableDatabase() throwing null pointer exception

限于喜欢 提交于 2020-01-13 13:11:12

问题


I have a service class having following code -

public class ReminderService extends WakeReminderIntentService{      
    private static final String TAG ="ReminderService";
    private TasksDBAdapter dbHelper;
    public ReminderService(){
        super("ReminderService");
        dbHelper = new TasksDBAdapter(this);
        dbHelper.open(); //THIS LINE GIVES ERROR
    }

code for TasksDBAdapter open() method is as -

    public TasksDBAdapter(Context ctx) {                                 
       this.mCtx = ctx;
   }

    public TasksDBAdapter open() throws android.database.SQLException {
           mDbHelper = new DatabaseHelper(mCtx);
           Log.i(TAG, "mDbHelper in open method-->" + mDbHelper);
           mDb = mDbHelper.getWritableDatabase(); // ACTUAL ERROR LINE
           return this;
       }

the log value receives address which means mDbHelper gets initialized properly.Log.i gives -

11-01 23:32:32.004: I/TasksDBAdapter(681): mDbHelper in open method-->ray.kaushik.simple.task.manager.TasksDBAdapter$DatabaseHelper@411e7a10

but

mDb = mDbHelper.getWritableDatabase();

throws the null pointer error.

Logcat gives -

11-01 23:32:32.043: E/AndroidRuntime(681): FATAL EXCEPTION: main
11-01 23:32:32.043: E/AndroidRuntime(681): java.lang.RuntimeException: Unable to instantiate service ray.kaushik.simple.task.manager.ReminderService: java.lang.NullPointerException
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.app.ActivityThread.handleCreateService(ActivityThread.java:2347)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.app.ActivityThread.access$1600(ActivityThread.java:130)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.os.Looper.loop(Looper.java:137)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.app.ActivityThread.main(ActivityThread.java:4745)
11-01 23:32:32.043: E/AndroidRuntime(681):  at java.lang.reflect.Method.invokeNative(Native Method)
11-01 23:32:32.043: E/AndroidRuntime(681):  at java.lang.reflect.Method.invoke(Method.java:511)
11-01 23:32:32.043: E/AndroidRuntime(681):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-01 23:32:32.043: E/AndroidRuntime(681):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-01 23:32:32.043: E/AndroidRuntime(681):  at dalvik.system.NativeStart.main(Native Method)
11-01 23:32:32.043: E/AndroidRuntime(681): Caused by: java.lang.NullPointerException
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
11-01 23:32:32.043: E/AndroidRuntime(681):  at ray.kaushik.simple.task.manager.TasksDBAdapter.open(TasksDBAdapter.java:38)
11-01 23:32:32.043: E/AndroidRuntime(681):  at ray.kaushik.simple.task.manager.ReminderService.<init>(ReminderService.java:16)
11-01 23:32:32.043: E/AndroidRuntime(681):  at java.lang.Class.newInstanceImpl(Native Method)
11-01 23:32:32.043: E/AndroidRuntime(681):  at java.lang.Class.newInstance(Class.java:1319)
11-01 23:32:32.043: E/AndroidRuntime(681):  at android.app.ActivityThread.handleCreateService(ActivityThread.java:2344)
11-01 23:32:32.043: E/AndroidRuntime(681):  ... 10 more

My databaseHelper class code -

    private static class DatabaseHelper extends SQLiteOpenHelper {          
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);      
        }
        @Override
        public void onCreate(SQLiteDatabase db) {                       
            db.execSQL(DATABASE_CREATE);                                
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {                                   

        }
    }

where DATABASE_NAME and all others have been defined globally -

private static final String DATABASE_NAME = "data";              
    private static final String DATABASE_TABLE = "reminders";        
    private static final int DATABASE_VERSION = 1;                   

    public static final String KEY_TITLE = "title";                  
    public static final String KEY_BODY = "body";
    public static final String KEY_DATE_TIME = "reminder_date_time"; 
    public static final String KEY_ROWID = "_id";                    
    private static final String TAG = "TasksDBAdapter";

can anyone please provide some pointers.. thanks in advance..!!!


回答1:


I believe the IntentService hasn't been fully initialized when you try to create the database in the constructor. Try moving your code into onHandleIntent():

protected void onHandleIntent(Intent intent) {
    dbHelper = new TasksDBAdapter(this);
    dbHelper.open();
    // Do something
}



回答2:


I kinda resolved the issue -

I have the class ReminderService where I was trying to call the dbHelper.open(); method.

Also this same class have one overridden method doReminderWork(intent) , where I was going to use the dbHelper initialized.

Earlier code -

  public ReminderService(){
            super("ReminderService");
            dbHelper = new TasksDBAdapter(this);
            dbHelper.open(); //THIS LINE GIVES ERROR
        }

    @Override
        void doReminderWork(Intent intent){ 

    /**
              * retrieve data about task
              */

             Cursor reminder = dbHelper.fetchReminder(rowId);
   }

in which i moved the open method in doReminderWork(Intent intent) method like -

public ReminderService(){
                super("ReminderService");
                dbHelper = new TasksDBAdapter(this);

            }

        @Override
            void doReminderWork(Intent intent){ 

        /**
                  * retrieve data about task
                  */
                dbHelper.open(); //MOVED HERE
                 Cursor reminder = dbHelper.fetchReminder(rowId);
       }

and it worked.. Can anyone give me proper detailed explanation why this worked as it was just a try that worked.




回答3:


This kind of actions must be called from a separate thread, Try to call it with a Thread object or AsyncTask.

Thread t = new Thread(new Runnable() { 
    public void run() {
        dbHelper.open(); //MOVED HERE
        Cursor reminder = dbHelper.fetchReminder(rowId);
    }
});
t.start();


来源:https://stackoverflow.com/questions/13183234/getwritabledatabase-throwing-null-pointer-exception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!