ContentValues getAsLong NullPointerException - android

I have a ContentValues that I'm parsing for data. I just received a very strange crash report:
Fatal Exception: java.lang.NullPointerException: Attempt to invoke
virtual method 'long java.lang.Long.longValue()' on a null object
reference
private void populateMeta(final ContentValues values)
{
if (values == null)
return;
Date d = new Date(values.getAsLong(Meta.Data.TIMESTAMP));
...
}
When I look in getAsLong I can't see how this could happen:
public Long getAsLong(String key) {
Object value = mValues.get(key);
try {
return value != null ? ((Number) value).longValue() : null;
} catch (ClassCastException e) {
if (value instanceof CharSequence) {
try {
return Long.valueOf(value.toString());
} catch (NumberFormatException e2) {
Log.e(TAG, "Cannot parse Long value for " + value + " at key " + key);
return null;
}
} else {
Log.e(TAG, "Cannot cast value for " + key + " to a Long: " + value, e);
return null;
}
}
}
It should just be returning null if the field is null, no?
Update:
Tried a few things to recreate that stack trace and in the end this narrowed it down:
values = new ContentValues();
Long timestamp = values.getAsLong(Meta.Data.TIMESTAMP); // null, as expected
Date d2 = new Date(timestamp); // source of error
Now here's the interesting thing. Adding a watch on new Date(timestamp) throws
NullPointerException: cannot unbox null value
which makes sense. However, letting that same line execute normally in code yields:
Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
Which I'm guessing is the root cause of the unbox error. I grasp unboxing, but I'm no expert, so I'd love a better explanation for why the stack trace seems so odd (and finicky) for this error. Thanks!

I had the same error, worked around by checking if such key exists with containsKey().
values.containsKey(Meta.Data.TIMESTAMP)
I am suspecting usage of weakreference to database results. Not exactly sure. Just adding a workaround here for this strange error.

Related

cursor.getLong(1) not throwing Exception

I have an field in database that is null
When I retrieve it in a cursor it is null.
I can tell that from the
cursor.isNull(1) is true
So when I do cursor.getLong(1) it should throw an exception according to the documentation. but it actually retrieves 0 without and exception.
any ideas why?
If you take a look at the implementation of the method getLong() in MatrixCursor , you can see the following code:
#Override
public long getLong(int column) {
Object value = get(column);
if (value == null) return 0;
if (value instanceof Number) return ((Number) value).longValue();
return Long.parseLong(value.toString());
}
If the value is null, then 0 is returned.

Save JSON to SQLite

I am making an android app and have to save JSON to an SQLite database.
The app already has a function to get JSON and display this in a listview and a function to save data to a database. Now I want to combine those, but I am a little lost.
public void get_data(String data) {
try {
JSONArray data_array=new JSONArray(data);
for (int i = 0 ; i < data_array.length() ; i++)
{
JSONObject obj=new JSONObject(data_array.get(i).toString());
Courses add=new Courses();
add.name = obj.getString("name");
add.ects = obj.getString("ects");
add.grade = obj.getString("grade");
add.period = obj.getString("period");
courses.add(add);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
This loops through the JSON so I think this is where is should save to the database.
public boolean insertCourse(String course, int ects, int period, int grade) {
SQLiteDatabase db = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COURSE_COLUMN_COURSE, course);
contentValues.put(COURSE_COLUMN_ECTS, ects);
contentValues.put(COURSE_COLUMN_PERIOD, period);
contentValues.put(COURSE_COLUMN_GRADE, grade);
db.insert(COURSE_TABLE_NAME, null, contentValues);
return true;
}
This is in a DBHelper.class should be able to use this I think.
I was hoping to reuse the code which i used to save input fields to the database but no luck so far.
else {
if(dbHelper.insertCourse(courseEditText.getText().toString(),
Integer.parseInt(ectsEditText.getText().toString()),
Integer.parseInt(periodEditText.getText().toString()),
Integer.parseInt(gradeEditText.getText().toString()))) {
Toast.makeText(getApplicationContext(), "Course Inserted", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "Could not Insert course", Toast.LENGTH_SHORT).show();
}
Does anyone have a suggestion how to integrate both (if possible at all).
Thnx in advance
EDIT:
the logcat crash report:
04-09 17:45:37.204 12244-12244/com.stefspakman.progress2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.stefspakman.progress2, PID: 12244
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.stefspakman.progress2.ProgressDBHelper.insertCourse(java.lang.String, int, int, int)' on a null object reference
at com.stefspakman.progress2.gradingActivity.get_data(gradingActivity.java:60)
at com.stefspakman.progress2.Download_data$1.handleMessage(Download_data.java:58)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5422)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
You need to instantiate your DBHelper class before using the insertCourse Method .
DBHelper helper = new DBHelper(this);
helper.insertCourse(Course course);
Also , its better if you use your Model class object as paramater for database queries .
public boolean insertCourse(Courses courses) {
SQLiteDatabase db = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COURSE_COLUMN_COURSE, courses.getCourse());
contentValues.put(COURSE_COLUMN_ECTS, courses.getEcts());
contentValues.put(COURSE_COLUMN_PERIOD, courses.getPeriod());
contentValues.put(COURSE_COLUMN_GRADE, courses.getGrade());
db.insert(COURSE_TABLE_NAME, null, contentValues);
return true;
}
In this way you can save your data from JSON as
db.insert(courses);
The exception says that your ProgressDBHelper is null, please make sure that you are creating an instance of ProgressDBHelper before calling its methods. Creating an instance is just calling ProgressDBHelper dbHelper = new ProgressDBHelper() and you have to call it before calling dbHelper.insertCourse(...)

Android char java.lang.String.charAt(int)' on a null object reference

I'm trying to get the first char from a string in an Array-adapter. After I run the application, it will work but while scrolling, the listview is crashing the application and I am getting the error:
java.lang.NullPointerException: Attempt to invoke virtual method 'char java.lang.String.charAt(int)' on a null object reference at this line char first = typenameRGN.charAt(0);
Here is my code in ArrayAdapter:
String typenameRGN = all_Post.getStrShortName();
Log.e("typenameRGN ", " = " + typenameRGN);
char first = typenameRGN.charAt(0);
Log.e("first ", " " + first);
String strTypeRGN = Character.toString(first);
Log.e("strTypeRGN ", " " + strTypeRGN);
holder.txtInitialLetter.setText(strTypeRGN);
Thanks.
Let check arrayadapter all_Post .
Maybe this array altered(clear,..) when listview scroll and it return null

close() was never explicitly called on database, DatabasedObjectNotClosed Exception?

I am getting following error even I have closed all instances as soon as I finish calling them:
close() was never explicitly called on database '/data/data/com.click4tab.fragmentvogella/databases/NewOrderDB'
android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
I was not getting this error until I defined this method.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
Toast.makeText(MainActivity.this, "Button one pressed",
Toast.LENGTH_LONG).show();
// write data on server
TestAdapter mDbHelper = new TestAdapter(this);
mDbHelper.createDatabase();
mDbHelper.open();
try {
mDbHelper.writeUnwrittenNetOrder();
mDbHelper.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
And the definition to writeUnwrittenNetOrder:
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
StringBuffer strbuf = new StringBuffer();
params.add(new BasicNameValuePair("tag", "add_NetOrderID"));
for (mCur.moveToFirst(); !mCur.isAfterLast(); mCur.moveToNext()) {
String sql3 = "INSERT into NetOrderID (StoreID, Date, SalesManID, NetOrderID) VALUES ("
+ mCur.getString(0)
+ ", "
+ mCur.getString(1)
+ ", "
+ mCur.getString(2) + ", " + mCur.getString(3) + ");";
if((mCur.isLast())){
strbuf.append(sql3);
}
else {
strbuf.append(sql3 + "#");
}
// String sql3 =
// "INSERT into NetOrderID (StoreID, SalesManID, NetOrderID) VALUES (1,1,80)";
// sqlQueries.add(sql3);
Log.e("sql", strbuf.toString());
}
params.add(new BasicNameValuePair("query", strbuf.toString()));
Log.e("param","param added");
new SyncWithServer();
// send params
SyncWithServer.setParams(params);
Log.e("param","param set");
// return arraylist
}
Where should I close the mDbHelper to avoid this error, well this error is coming up in Logcat while the database is getting successfully written and the Application is not crashing.
The error message says you did not close database or cursor. Did you close all of them as well (mCur object)?
Alex makes a good point.
And also (but I don't think that's what's causing the error right now): I think it is better to take the mDbHelper.close() statement out of the try/catch, or put it in a finally clause. Because currently, when writeUnwrittenNetOrder throws an exception, mDbHelper.close() will never be called. Something comparable will yields for when you're adding the cursor close method as Alex suggested: this should also happen regardless of exceptions that occur between open and close.

Database values are some times updated but sometimes not?

I have written a simple code for Database updatation, but it is sometime updating and sometimes not... i have written LOG for conformation but the log is giving correct output. Here is what i am trying :=
public void updateDownloadedAssetNumberOfStartingBytesEncrypted(int id, int startingBytesEncrypted)
{
SQLiteDatabase database = null;
int numOfRowsUpdated = 0;
try
{
database = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("StartingBytesEncrypted", startingBytesEncrypted);
if(database.isOpen())
{
Log.v("updating in db","doc id - "+id + " encrypted bytes - "+startingBytesEncrypted);
numOfRowsUpdated = database.update("_assets", values, "Id = "+id, null);
}
else
{
Log.v("Database","the database is not open thus starting encrypted bytes were not updated");
}
Log.v("muber of rows updated - ",""+numOfRowsUpdated);
}
catch(Exception ex)
{
}
finally
{
if(database != null)
{
database.close();
}
}
}
What is the problem?? Any help would be Appreciable.
Ya i got ur code...
Finally i resolved the issue.... actually it is beacuse of threading....
the thread creating the row was executed later and that updating the row was executed first
i have resolved it.Have fun :)
This happened due to connection of database is not open. Pls keep ex.printstacktrace(); in catch statement.

Categories

Resources