Andre Yonadam
Andre Yonadam

Reputation: 1024

ASyncTask causing getDatabaseLocked

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

Answers (1)

laalto
laalto

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

Related Questions