Reputation: 1024
I have a dedicated class called CheckForUpdates
extending ASyncTask that parses a JSON file from the internet. The class CheckForUpdates is created and the update method is called from the main activity. I use a class called DatabaseHandler that extends SQLiteOpenHelper and manages the database. However, no matter what I do, I always get the error getDatabaseLocked when I try adding something to the database which also has a class that manages it. I have already tried closing all the open cursors and databases, deleting the other instance of CheckForUpdates in the MainActivity and even tried passing an instance of DatabaseHandler to the class CheckForUpdates which gets me a nullPointerException. As you can see that I have tried a lot of things to try to resolve the situation but it seems that the Asynctask is locking the SQLite database regardless of the coding being in the Asynctask's onPostExecute or doInBackground()
.
EDIT Not sure if a content provider may help in this case but I was wondering why it isn't working right now directly.
MainActivity.class
package com.andreyonadam.Contacts;
import com.andreyonadam.Contacts.R;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.widget.Toast;
@SuppressLint("NewApi")
public class MainActivity extends Activity {
DatabaseHandler DBHandler;
CheckForUpdates CheckForUpdates;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DBHandler = new DatabaseHandler(this);
CheckForUpdates = new CheckForUpdates(this.getApplicationContext());
CheckForUpdates.check(this, DBHandler);
}
private void databaseUpdateLists() {
// TODO Auto-generated method stub
if(!DBHandler.getAllOne().isEmpty() && !DBHandler.getAllTwo().isEmpty()){
//fetch the SQL to local Array
}else{
Toast toast = Toast.makeText(this, Integer.toString(DBHandler.getAllOne().size()), 1000);
toast.show();
//fetch the SQL to local Array
}
}
}
CheckForUpdates.class
package com.andreyonadam.Contacts;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
public class CheckForUpdates extends AsyncTask<URL, Void, JSONObject> {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
JSONArray contacts = null;
public final int version = 0;
Context context;
DatabaseHandler DBHandler;
public CheckForUpdates(Context c){
context = c;
}
public CheckForUpdates(){
}
public void check(Context c, DatabaseHandler dBHandlertemp){
context = c;
new CheckForUpdates().execute();
}
public JSONObject getJSONFromUrl(String url) {
Log.d("Update Check", "Started");
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
@Override
protected JSONObject doInBackground(URL... params) {
// TODO Auto-generated method stub
JSONObject json = getJSONFromUrl("http://www.myurl.com/test/demo.json");
return json;
}
protected void onPostExecute(JSONObject jsonObj) {
DBHandler = new DatabaseHandler(context);
ArrayList<Double> one = new ArrayList<Double>();
ArrayList<Double> two = new ArrayList<Double>();
//If it wasn't able to get the JSON file it will return null
if(jsonObj != null){
try {
// Getting Array of Contacts
contacts = jsonObj.getJSONArray("test");
// looping through All Contacts
for(int i = 0; i < contacts.length(); i++){
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
one.add(c.getDouble("1"));
two.add(c.getDouble("2"));
//Fill array then copy
}
} catch (JSONException e) {
e.printStackTrace();
}
DBHandler.addContacts(one, two);
}
}
}
DatabaseHandler.class
package com.andreyonadam.Contacts;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "test";
// Contacts table name
private static final String TABLE_MAIN = "Main";
// Contacts Table Columns names
private static final String KEY_NAME = "name";
private static final String KEY_LOCATION_ONE = "one";
private static final String KEY_LOCATION_TWO = "two";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_MAIN + " ( " +
KEY_LOCATION_ONE + " INTEGER, " +
KEY_LOCATION_TWO + " INTEGER "+ " )";
db.execSQL(CREATE_CONTACTS_TABLE);
db.close();
}
// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_MAIN);
// Create tables again
onCreate(db);
db.close();
}
public List<Double> getAllOne() {
List<Double> contactList = new ArrayList<Double>();
// Select All Query
String selectQuery = "SELECT " + KEY_LOCATION_ONE + " FROM " + TABLE_MAIN;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
contactList.add(cursor.getDouble(0));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
// return contact list
return contactList;
}
public List<Double> getAllTwo() {
List<Double> contactList = new ArrayList<Double>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_MAIN;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
contactList.add(cursor.getDouble(0));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
// return contact list
return contactList;
}
void addContact(Double One, Double Two) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_LOCATION_ONE, One); // Contact Phone
values.put(KEY_LOCATION_ONE, Two); // Contact Phone
// Inserting Row
db.insert(TABLE_MAIN, null, values);
db.close(); // Closing database connection
}
void voidAddTwo(ArrayList<Double> list){
}
void deleteAllRows(){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_MAIN, null, null);
db.close();
}
void addContacts(ArrayList<Double> one, ArrayList<Double> two){
synchronized(this) {
SQLiteDatabase db = this.getWritableDatabase();
String values = null;
for(int i = 0; i <one.size(); i++){
values = values.concat("(" + one.get(i) + ", " + two.get(i) + ")");
if(i != one.size()-1){
values.concat(",");
}
}
String CREATE_CONTACTS_TABLE = "INSERT INTO " + TABLE_MAIN + "VALUES " +
values + "";
db.execSQL(CREATE_CONTACTS_TABLE);
db.close();
}
}
}
Upvotes: 0
Views: 90
Reputation: 152847
getDatabaseLocked()
is just a method in SQLiteOpenHelper
and you see it in your NPE stacktrace when you've passed a null
for a Context
and are attempting to open the database.
Where the null comes from: CheckForUpdates
has two constructors of which only the other initializes your context
member variable that gets passed to the sqlite helper. CheckForUpdates.check()
creates a new CheckForUpdates
instance using the constructor that doesn't initialize context
. Bang.
Remove the no-arg constructor that does not initialize context
.
check()
is a method of CheckForUpdates
already. Probably it shouldn't be creating new CheckForUpdates
instances itself.
Upvotes: 1