SQLite unable to open database file (code 14) on frequent “SELECT” query

后端 未结 5 782
無奈伤痛
無奈伤痛 2020-12-16 04:09

I have following class \"Singleton\" to handle SQLite connection and to make sure to have 1 instance of connection for whole process/app:

public class DBCon         


        
相关标签:
5条回答
  • 2020-12-16 04:35

    I am using cursor for a big query where cursor hit the DB more than 1350 times by three seperate 'QUERY' within 800 milliseconds. So I got the error (android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)). I solved it by closing the cursor before start a new query. That resolves my problem. Hope it will work the more big query than mine.

    String data_query = "SELECT * FROM test WHERE id= " + c_id + " AND memberId = " + memberId;           
    Cursor cu_cu = userHelper.getData(data_query);
    float cu_cu_count = cu_cu.getCount();
    System.out.println("ALL ANSWER COUNT : " + cu_cu_count);
    cu_cu.close();
    
    0 讨论(0)
  • 2020-12-16 04:37

    In your Application class

    public static SQLiteDatabase database;
    
    @Override
    public void onCreate() {
        super.onCreate();
    
        SQLiteOpenHelper helper = Database.getInstance(getApplicationContext());
    
        if (database == null) {
            database = helper.getWritableDatabase();
        } else {
            if (!database.isOpen()) {
                database = helper.getWritableDatabase();
            }
        }
    }
    

    In your queries class

     public DataSources() {
        database = ApplicationController.database;
     }
    

    That way you create a writeable db object once

    0 讨论(0)
  • 2020-12-16 04:42

    Your code re-opens the database every time dbOpen() is called.

    An SQLite database object is quite lightweight; it does not really make sense to keep closing and re-opening it.

    You already have your singleton; just store a single SQLiteDatabase reference there.

    0 讨论(0)
  • 2020-12-16 04:43

    before executing any query to this stuff (You should open your database). Close db after completion the task.

    private DBHelper dbHelper = new DBHelper(context);
    
    try {
        _db = dbHelper.getWritableDatabase();
    } catch (SQLException s) {
        new Exception("Error with DB Open");
    }
    

    // Then write your query now.... and then close the db.

    _db.close();
    

    You can check out my git link1 git link2

    0 讨论(0)
  • 2020-12-16 04:55

    As an addition, I believe that having too many cursors, and thus open's, can also result in the same "unable to open database file error". (in the following code, there's 507 rows in the shoplistcursor, so that was over 1500 cursors used/reused in total)

    I was getting the same message. As per :-

    10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
    10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) os_unix.c:30046: (24) open(/data/data/mjt.shopper/databases/Shopper-journal) - 
    10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
    10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) os_unix.c:30046: (24) open(/data/data/mjt.shopper/databases/Shopper-journal) - 
    10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) statement aborts at 24: [SELECT *  FROM productusage WHERE productailseref = 60 AND productproductref = 75 ;] unable to open database file
    10-29 19:57:00.902 12845-12845/mjt.shopper E/SQLiteQuery: exception: unable to open database file (code 14); query: SELECT *  FROM productusage WHERE productailseref = 60 AND productproductref = 75 ;
    10-29 19:57:00.902 12845-12845/mjt.shopper D/AndroidRuntime: Shutting down VM
    10-29 19:57:00.903 12845-12845/mjt.shopper E/AndroidRuntime: FATAL EXCEPTION: main
    

    The code, that was in error, was :-

     SQLiteDatabase db = getWritableDatabase();
            Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
            Cursor productcsr;
            Cursor aislecsr;
            Cursor prdusecsr;
            while(shoplistcursor.moveToNext()) {
                productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
                aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
                prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                        shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
                if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                    deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
                } 
                if(shoplistcursor.isLast()) {
                    prdusecsr.close();
                    aislecsr.close();
                    productcsr.close();
                }
            }
            shoplistcursor.close();
            db.close();
    }
    

    The cure was to close the cursors on each iteration. As per :-

     SQLiteDatabase db = getWritableDatabase();
            Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
            Cursor productcsr;
            Cursor aislecsr;
            Cursor prdusecsr;
            while(shoplistcursor.moveToNext()) {
                productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
                aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
                prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                        shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
                if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                    productcsr.close();
                    aislecsr.close();
                    prdusecsr.close();
                    deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
                } else {
                    productcsr.close();
                    aislecsr.close();
                    prdusecsr.close();
                }
            }
            shoplistcursor.close();
            db.close();
        }
    
    0 讨论(0)
提交回复
热议问题