I am getting null pointer exception while fetching the data from the SQLite table.
I am getting the null pointer exception when fetching the data using cursor like below Cursor c= db.fetchAllData();
Please have a look at the below precise code, and suggest me some ideas...
display_transaction.class
public class display_transaction extends Activity {
DisplayTestDBHelper db;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_listview);
displayListView();
}
public void displayListView() {
Cursor c= db.fetchAllData();
String[] columns={db.KEY_ID,db.KEY_DESCRIPTION,db.KEY_AMOUNT};
int[] id=new int[]{R.id.textView1,R.id.textView2};
SimpleCursorAdapter s=new SimpleCursorAdapter(this,R.layout.listviewlayout,c,columns,id,0);
ListView l=(ListView) findViewById(R.id.listview1);
l.setAdapter(s);
}
}
DisplayTestDBHelper.class
public Cursor fetchAllData() {
String TABLE_NAME="transaction_table";
SQLiteDatabase db = this.getWritableDatabase();
Cursor mCursor = db.query(TABLE_NAME, new String[] {KEY_ID, KEY_DESCRIPTION, KEY_AMOUNT}, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
Please help me to resolve the above issue...
Thanks in advance!!!!
You didn't initialize db.
Depending on how you've implemented the helper's constructor, use something like
db = new DisplayTestDBHelper(this);
to init it, passing the activity this for a Context.
You haven't initialized db.
You need to do something like:
db = new DisplayTestDBHelper(this);
Related
please I would need your help to figure out, why these code lines do not work.
I would like to fill a list with String elements taken from the database.
This is the mothod fillTheList() which returns a list:
public List<String> fillTheList() {
List<String> list = new ArrayList<String>();
//My database is called "ITEMS_" and the first column is called "typeOfItem"
String[] column = {"typeOfItem"};
String selection = "SELECT DISTINCT type FROM ITEMS_";
Cursor cursor = MainActivity.sqLiteHelper.getDataCategories("ITEMS_", column, selection);
if(cursor != null) {
list.clear();
if (cursor.moveToFirst()) {
do {
String type = cursor.getString(1);
list.add(type);
} while (cursor.moveToNext());
}
}
Log.d("List", cursor.getString(1));
return list;
}
The getDataCategories() is a mehod of the sqLiteHelper-class
public Cursor getDataCategories(String table, String[] columns, String selection )
{
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.query(true, table, new String[] {String.valueOf(columns)}, selection,
null, null, null, null, null);
return cursor;
}
The error occurs at:
Cursor cursor = MainActivity.sqLiteHelper.getDataCategories("ITEMS_", column, selection); and the logcat is:
"Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor SQLiteHelper.getDataCategories(java.lang.String, java.lang.String[], java.lang.String)' on a null object reference"
The error log indicates that MainActivity.sqLiteHelper is null.
I don't know in which class you have fillTheList(), but you deal with the issue of filling the list in a wrong way.
Change fillTheList() it like:
public List<String> fillTheList() {
List<String> list = new ArrayList<>();
Cursor cursor = sqLiteHelper.getDataCategories();
if(cursor != null) {
if (cursor.moveToFirst()) {
do {
list.add(cursor.getString(0));
} while (cursor.moveToNext());
}
}
return list;
}
As you can see you must supply a context for the initialization of SQLiteHelper to fetch the cursor and populate the list.
Then change getDataCategories() to this:
public Cursor getDataCategories() {
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery("SELECT DISTINCT typeOfItem FROM ITEMS_", null);
}
This method uses rawQuery() which is simpler and not query().
I don't know if the name of the column is typeOfItem or type, so if you need change the sql statement.
Now you can use fillTheList() if first you have a valid SQLiteOpenHelper object, say sqlObject, like:
List<String> list = sqlObject.fillList();
I am trying to populate the ListFragment from one of the columns in my Database.
For that i am trying to use
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
db.open();
db = new NotesDatabase(getActivity());
c = db.getAllRows();
getActivity().startManagingCursor(c);
String[] fromField = new String[] { NotesDatabase.KEY_TITLE };
int[] toView = new int[] { R.id.item_title };
SimpleCursorAdapter myCAdapter = new SimpleCursorAdapter(getActivity(),
R.layout.list_item, c, fromField, toView, 0);
setListAdapter(myCAdapter);
}
but i dont know why i am getting a NullPointerException on db.open(); and c = db.getAllRows();
db.open()
public NotesDatabase open() {
db = myDBHelper.getWritableDatabase();
return this;
}
db.getAllRows();
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null,
null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
DBHelper
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
or if there is a better a better way to populate the list view of fragment from a database?
Thanks in Advance :)
db.open();
db = new NotesDatabase(getActivity());
c = db.getAllRows();
Open the database
Create the database
Get all the rows.
Logically speaking. create it first. then open. then get all the rows. So swithc line 1 and lone 2.
Another thing is that , I assume your getting NPE at myDBHelper, because you never created that helper.
aren't you doing it reverse?
db.open();
db = new NotesDatabase(getActivity());
Just initialise your databasehelper before opening it:
db = new DatabaseHelper(this);
You are doing the db.open before the new so it doesn't exist yet, you are trying to open a null db.
This question already has an answer here:
attempt to re-open an already-closed object: SQLiteDatabase
(1 answer)
Closed 8 years ago.
I know there are several questions like this one, but all of them seem to have a different approach to solve the problem and none have solved mine.
I have my main activity working just fine, loading the db and populating the listview. Then I call a second activity and the problem shows up when I try to load the listview.
I have tried using start/stop managingcursor(cursor) even though it is deprecated, but it didn't fix the problem. Also I tried cloasing the cursor and db in my main activity before firing the next one but that didn't help either.
Both classes extend from ListActivity and follow the same sequence:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Open db in writing mode
MySQLiteHelper.init(this);
MySQLiteHelper tpdbh =
new MySQLiteHelper(this, "DB", null, 1);
SQLiteDatabase db = tpdbh.getWritableDatabase();
checkLocationAndDownloadData(); //this fires a Asynctask that calls method parseNearbyBranches shown bellow
//I load the data to the ListView in the postExecute method of the asynctask by calling:
/*
Cursor cursor = MysSQLiteHelper.getBranchesNames();
adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String branch_id = cursor.getString(cursor.getColumnIndexOrThrow("branch_id"));
cursor.close();
openNextActivity(Integer.parseInt(branch_id));
}
});
}
//In another file:
private void parseNearbyBranches(JSONObject jo) throws JSONException
{
if ( jo.has(jsonTitle) &&
jo.has("company_id") &&
jo.has("id")
) {
String branch = jo.getString(jsonTitle);
MySQLiteHelper tpdbh = MySQLiteHelper.instance;
SQLiteDatabase db = tpdbh.getWritableDatabase();
db.execSQL("INSERT INTO Branches (branch_id, name, company_id) " +
"VALUES ('" +jo.getInt("id")+"', '" + branch +"', '" +jo.getInt("company_id")+"' )");
db.close(); //no difference is I comment or uncomment this line
}
}
In MySQLiteHelper.java:
public static Cursor getBranchesNames() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id", "branch_id", "name", "company_id" };
Cursor c = getReadDb().query(branchesTable, columns, null, null, null, null,
null);
return c;
}
My other activity does basically the same:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_branch_surveys);
//Read branch data from DB
int companyID = -1;
MySQLiteHelper.init(this);
String [] columns = new String [] {"company_id"};
String [] args = {Integer.toString(branchID)};
Cursor c = MySQLiteHelper.getReadDb().query(MySQLiteHelper.branchesTable, columns, "branch_id=?", args, null, null, null); //THIS QUERY WORKS JUST FINE
if (c.moveToFirst())
companyID = Integer.parseInt(c.getString(0));
c.close();
if( companyID != -1)
{
new DownloadTask().execute(Integer.toString(companyID) );
//where the Async task calls something just like NearByBranches shown above(but with different objects of course)
//And the postExecute sets the listView:
/* cursor = MySQLiteHelper.getAll();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
}
}
}
In MySQLiteHelper.java:
public static Cursor getAll() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id","title", "points" };
//********IT IS IN THIS LINE WHERE I GET THE ERROR:********************
Cursor c = getReadDb().query(theTable, columns, null, null, null, null,
null);
return c;
}
public static SQLiteDatabase getReadDb() {
if (null == db) {
db = instance.getReadableDatabase();
}
return db;
}
I hope you can help me out. Thanks!
I just tried commenting the db.close in the similar method of parseNeabyBranches and the problem was solved. Yet I dont get the same error having db.close() in parseNearbyBranches(), can you explain me why?
In parseNearbyBranches() you create a separate SQLiteDatabase object with:
SQLiteDatabase db = tpdbh.getWritableDatabase();
Since this is a different object than the one returned by getReadDb(), you can (and should) close it. The basic rule is each time you call getWritableDatabase() and getReadableDatable() you must have a matching close() statement.
I have been trying every single thing but still some how have not been able to find a solution for this. In spite of using the close method the cursor still doesn't seem to be closing. This has been frustrating me. Any help will be much appreciated. Here is my code
public class Order extends Activity{
DatabaseHelper helper;
Cursor c;
SQLiteDatabase db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.order);
String columns[] = {"_id", "Name", "Price"};
helper = new DatabaseHelper(this);
db=helper.getWritableDatabase();
c=db.query("lite", columns, null, null, null, null, null);
c.moveToFirst();
curs();
c.close();
helper.close();
}
public void curs()
{
String r = "";
while(!c.isAfterLast())
{
r=r + c.getString(c.getColumnIndex("_id")) + " "+c.getString(c.getColumnIndex("Name"))+" "+c.getString(c.getColumnIndex("Price"));
c.moveToNext();
}
}
Modify
curs();
c.close();
helper.close();
to
curs();
if(!isClosed()){
c.close();
}
helper.close();
db.close();
You have not closed your database also, try this
db.close();
c.close();
helper.close();
Also, I suggest you can declare 'Cursor' as local variable instead of global and pass it as in argument to your method 'curs'
I am trying to fetch rows from the database and make a list view from it.
This is by Query method inside the DbAdapter
public Cursor readInbox(long toId) throws SQLException {
return db.query(TABLE_MAILS, new String[] { ID, KEY_FROM, KEY_TO,
KEY_SUB, KEY_BODY, KEY_DATETIME, KEY_READ }, KEY_TO + "="
+ toId, null, null, null, null, null);
}
This is the code i am trying to write. but its giving error
public class InboxActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inbox);
DBAdapter db = new DBAdapter(InboxActivity.this);
db.open();
long userID = Long.parseLong(MessagingApplication.getUserID());
Cursor inbox = db.readInbox(userID);
startManagingCursor(inbox);
String[] Id = new String[] { DBAdapter.ID };
SimpleCursorAdapter inboxmail = new SimpleCursorAdapter(this, R.layout.list_view, db, Id, null);
setListAdapter(inboxmail);
db.close();
}
}
the Error:
The constructor SimpleCursorAdapter(InboxActivity, int, DBAdapter, String[], null) is undefined
This is a simple compilation error.
Have a look at the public constructors at http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html :
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
You're providing DBAdapter where you should be providing a Cursor. Most likely you should be passing the inbox variable instead of DBAdapter