-3

This code runs perfectly in API level 21 but it is not working in API level 19. It is producing a NullPointerException.

I have checked out a lot of problems related to this on Google, but they have not been helpful.

I am calling SQliteOpenHelper from a child fragment, so here is my code with errors:

// This is my Chatbox class which a childfragment and
// I am calling this method to pass values in sqlite class

 private void saveConversation(String profile_name,String profile_id,String message,String who){
    sqLite = new SQLite(getContext());
    SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
    sqLite.onCreate(sqLiteDatabase);
    sqLite.insert(profile_name, profile_id, message, who);
}


//Sqlite class
public class SQLite extends SQLiteOpenHelper {
     SQLiteDatabase sqLiteDatabase  =  this.getWritableDatabase();
     ContentValues contentValues;
    Context context;

    public static final String DatabaseName = "Communication";
    public static final String TableName1  = "ChatConversation";
    public static final int DatabaseVersion = 2;

    public SQLite(Context context) {
        super(context, DatabaseName, null, DatabaseVersion);
        this.context = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
            Toast.makeText(context,"on create table is called !!",Toast.LENGTH_SHORT).show();
            db.execSQL("CREATE TABLE IF NOT EXISTS "+TableName1+"(_id INTEGER PRIMARY KEY AUTOINCREMENT,profilename VARCHAR(50),profileid VARCHAR(50),message VARCHAR(255),who VARCHAR(20))");
    }

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

    }

    public void insert(String profilename,String profileid ,String message, String who){
        Toast.makeText(context,"insert database was called",Toast.LENGTH_LONG).show();
        contentValues = new ContentValues();
        contentValues.put("profilename",profilename);
        contentValues.put("profileid",profileid);
        contentValues.put("message",message);
        contentValues.put("who",who);
        long id = sqLiteDatabase.insert(SQLite.TableName1,null,contentValues);
        if(id>0){
           Toast.makeText(context,"successfully inserted", LENGTH_LONG).show();
        }else{
            Toast.makeText(context,"Something went wrong", LENGTH_LONG).show();
        }
    }

}

Here is my error:

com.example.shuresnepali.communicationpost, PID: 21374
   java.lang.NullPointerException
   at android.widget.Toast.<init>(Toast.java:117)
   at android.widget.Toast.makeText(Toast.java:275)
   at com.example.shuresnepali.communicationpost.SQLite.onCreate(SQLite.java:28)
   at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
   at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
   at com.example.shuresnepali.communicationpost.SQLite.<init>(SQLite.java:13)
   at com.example.shuresnepali.communicationpost.Chat_box.saveConversation(Chat_box.java:283)
   at com.example.shuresnepali.communicationpost.Chat_box.onClick(Chat_box.java:149)
   at android.view.View.performClick(View.java:4652)
   at android.view.View$PerformClick.run(View.java:19318)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:146)
   at android.app.ActivityThread.main(ActivityThread.java:5641)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1288)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1104)
   at dalvik.system.NativeStart.main(Native Method)
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Shures
  • 25
  • 1
  • 7
  • Possible duplicate: [What is a Null Pointer Exception and how do I fix it](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it). By the way, reopening a duplicate is an anti-pattern – Phantômaxx Aug 28 '17 at 10:31
  • @ModularSynth I reopened since I find closing questions as duplicate to a generic problem-solving approach unhelpful if there is a more specific problem. It's good reference but rarely helps in specific problems. – laalto Aug 28 '17 at 10:42
  • Thank you @laalto for helping me out i just pass sqliteDatabase through the insert method during inserting data in sqlit. thaks again your answer was very supportive – Shures Aug 28 '17 at 10:53
  • @laalto EVERY NullPointerException has the SAME origin. Therefore, *seen ONE, seen ALL*. They are ALL fixed by correctly instancing the prematurely referenced object. The duplicate should remain. – Phantômaxx Aug 28 '17 at 11:12

4 Answers4

1

try this use getActivity() in fragment to get Context

private void saveConversation(String profile_name,String profile_id,String message,String who){
        sqLite = new SQLite(getParentFragment().getActivity());
        SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
        sqLite.onCreate(sqLiteDatabase);
        sqLite.insert(profile_name, profile_id, message, who);
    }
AskNilesh
  • 67,701
  • 16
  • 123
  • 163
  • thank you for your quick respond but still no change got the same error as before....i am using childfragment so does it matter ? – Shures Aug 28 '17 at 10:25
  • Still didn't work i also tried getParentFragment().getcontex() but still got the same error. it works in api level 21 so would you please consider on that issue ? but not working in api 19 at all. – Shures Aug 28 '17 at 10:45
  • @Shures check this link https://stackoverflow.com/questions/31297539/how-to-get-the-activity-in-nested-fragments – AskNilesh Aug 28 '17 at 10:51
1

Use getActivity() for getting Context in fragment;

 private void saveConversation(String profile_name,String profile_id,String message,String who){
        sqLite = new SQLite(getActivity());
        SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
        sqLite.onCreate(sqLiteDatabase);
        sqLite.insert(profile_name, profile_id, message, who);
    }
Vishal Vaishnav
  • 3,346
  • 3
  • 26
  • 57
1
public class SQLite extends SQLiteOpenHelper {
      SQLiteDatabase sqLiteDatabase  =  this.getWritableDatabase();

You're calling getWritableDatabase() too early. In Java, member initializers run before constructor body (other than explicit super constructor calls), and you're only initializing context in your constructor body. getWritableDatabase() in turn calls back to onCreate() where you are using the context field that is not yet initialized. Further reading: Java order of Initialization and Instantiation

Remove this field, or postpone its initialization to constructor body.

On a related note, you should not call onCreate() yourself.

Why it "works" on API 21 and not 19 is likely because on your API 21 device/emulator you already have a database file with the same name, created with an earlier version of your app without this bug. getWritableDatabase() only calls back to onCreate() if the database file didn't exist. When is SQLiteOpenHelper onCreate() / onUpgrade() run?

laalto
  • 150,114
  • 66
  • 286
  • 303
  • Would you please clear more on this ? i have also heard about this issue but not being able to understand what is going on ?? it would be nice if you help me out ? – Shures Aug 28 '17 at 10:39
  • Remove this `getWritableDatabase()` field initializer, and remove the line where you call `onCreate()`. Call `getWritableDatabase()` to init a local var in those methods where you need `SQLiteDatabase()`. – laalto Aug 28 '17 at 10:40
0

Thanks everyone for your help i solve this by ...passing context during insert data, and removed the getwriteabledatabase from initilization

 private void saveConversation(String profile_name,String profile_id,String message,String who){
        sqLite = new SQLite(getParentFragment().getContext());
        SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
        sqLite.onCreate(sqLiteDatabase);
        sqLite.insert(profile_name, profile_id, message, who,sqLiteDatabase);
    }
//and after this
 public void insert(String profilename,String profileid ,String message, String who,SQLiteDatabase sqLiteDatabase){
        Toast.makeText(context,"insert database was called",Toast.LENGTH_LONG).show();
        contentValues = new ContentValues();
        contentValues.put("profilename",profilename);
        contentValues.put("profileid",profileid);
        contentValues.put("message",message);
        contentValues.put("who",who);
        long id = sqLiteDatabase.insert(SQLite.TableName1,null,contentValues);
        if(id>0){
           Toast.makeText(context,"successfully inserted", LENGTH_LONG).show();
        }else{
            Toast.makeText(context,"Something went wrong", LENGTH_LONG).show();
        }
    }
Shures
  • 25
  • 1
  • 7