代码之家  ›  专栏  ›  技术社区  ›  Jayesh

Sqlite数据库在三星Android Oreo 8.0设备中运行不正常

  •  3
  • Jayesh  · 技术社区  · 6 年前

    我创建了一个应用程序,它只执行一些数据库读取操作(从数据库中获取记录并执行一些公式并显示结果)

    联想(5.1.1)、Moto(5.1、6.0、7.1.1)、OnePlus(8.1)、Mi A1(8.0.0)、Micromax(5.0)、三星(7.1)

    设备是 三星galaxy J8(SM-J810G)、三星galaxy S7(SM-G930W8)、三星galaxy S9(SM-G960U)。

    数据库查询.java

    package com.test.dbhelper;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteException;
    import android.database.sqlite.SQLiteOpenHelper;
    
    import com.test.common.DBConstants;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class DBAdapter extends SQLiteOpenHelper implements DBConstants {
    private static String DB_PATH = "";
    
    private SQLiteDatabase mDB;
    
    private static int DB_VERSION = 1;
    private Context appContext;
    
    public DBAdapter(Context context) {
        super(context.getApplicationContext(), DB_NAME, null, DB_VERSION);
        DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        appContext = context;
        createDataBase();
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        System.out.println("DB Helper On Create....");
        this.mDB = db;
        createDataBase();
    }
    
    public void createDataBase() {
        SQLiteDatabase db_Read = null;
        try {
            boolean dbExist = checkDataBase();
            if (dbExist) {
            } else {
                db_Read = this.getReadableDatabase();
                db_Read.close();
                try {
                    copyDataBase();
                } catch (IOException e) {
                    throw new Error("Error copying database");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private boolean checkDataBase() {
    
        try {
            String myPath = DB_PATH + DB_NAME;
            mDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
        }
        if (mDB != null) {
            mDB.close();
        }
        return mDB != null ? true : false;
    }
    
    private void copyDataBase() throws IOException {
    
        InputStream myInput = appContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[1024];
        int length;
    
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
    
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }
    
    public void openDataBase() {
        try {
            String myPath = DB_PATH + DB_NAME;
            mDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch (Exception e) {
            System.out.println("Open Database failed...");
            e.printStackTrace();
        }
    }
    
    public DBAdapter open() throws SQLException {
        mDB = getWritableDatabase();
        return this;
    }
    
    @Override
    public synchronized void close() {
        if (mDB != null)
            mDB.close();
        super.close();
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
    }
    
    public int insertData(String table_name, ContentValues initialValues) {
        int record = (int) mDB.insert(table_name, null, initialValues);
        return record;
    }
    
    public int deleteData(String table_name, String whereClause) {
        return (int) mDB.delete(table_name, whereClause, null);
    }
    
    public int updateData(String table_name, ContentValues initialValues,
                          String whereClause) {
        return mDB.update(table_name, initialValues, whereClause, null);
    }
    
    public Cursor executeRawQuery(String query) {
        Cursor c = null;
        c = mDB.rawQuery(query, null);
    
        return c;
    }
    

    }

    package com.test.common
    
    interface DBConstants {
      companion object {
        const val DB_NAME = "test.db3"
        const val TAB_WELL_RITE = "well_rite"
        const val TAB_WELL_RITE_TANK_VOLUME_IN_GALLON = "tank_volume_in_gallon"
        const val TAB_WELL_RITE_MODEL_WELL_RITE = "model_well_rite"
        const val TAB_WELL_RITE_MODEL_CHALLANGER = "model_challanger"
        const val TAB_WELL_RITE_MODEL_FLEX_LITE = "model_flex_lite"
        const val TAB_WELL_RITE_TANK_VOLUME_IN_LITRE = "tank_volume_in_litre"
      }
    }
    

    数据库查询.java

    package com.test.dbhelper;
    
    import android.database.Cursor;
    
    import com.test.activity.TestApp;
    import com.test.common.Constants;
    import com.test.common.DBConstants;
    import com.test.common.LogUtils;
    
    import java.util.HashMap;
    
    public class DBQuery implements DBConstants, Constants {
    
    public static String TAG = "DBQuery";
    
    public static HashMap<String, String> getWellRiteModels(String tableName, String field, double value) {
    
        HashMap<String, String> dataMap = new HashMap<>();
    
        String query = "SELECT * " + " FROM " + tableName
                + " WHERE " + field + " >= '" + value + "' order by " + field + " LIMIT 1";
    
        Cursor cursor = TestApp.dbAdapter.executeRawQuery(query);
    
        if (cursor.getCount() > 0) {
            if (cursor.moveToFirst()) {
                dataMap.put(WELL_RITE, cursor.getString(1));
                dataMap.put(CHALLANGER, cursor.getString(2));
                dataMap.put(FLEX_LITE, cursor.getString(3));
            }
        }
        return dataMap;
      }
    }
    

    测试pp.kt

    package com.test.activity
    
    import android.app.Application
    import com.crashlytics.android.Crashlytics
    import com.test.dbhelper.DBAdapter
    import io.fabric.sdk.android.Fabric
    
    class TestApp : Application() {
    
      companion object {
        lateinit var dbAdapter: DBAdapter
      }
    
      override fun onCreate() {
        super.onCreate()
        Fabric.with(this, Crashlytics())
        dbAdapter = DBAdapter(applicationContext)
        dbAdapter.openDataBase()
      }
    }
    

    var dataMap: HashMap<kotlin.String, kotlin.String> = HashMap()
    dataMap = DBQuery.getWellRiteModels(TAB_WELL_RITE, DBConstants.TAB_WELL_RITE_TANK_VOLUME_IN_GALLON, 32.50)
    

    我有test.db3数据库,在assets文件夹中有记录。

    三星Android 8.0的设备有什么特别的问题吗?

    下面是错误日志

    Fatal Exception: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/user/0/com.test/databases/test.db3
       at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
       at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1742)
       at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1685)
       at com.test.dbhelper.DBAdapter.executeRawQuery(DBAdapter.java:147)
       at com.test.dbhelper.DBQuery.getWellRiteModels(DBQuery.java:26)     
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Khyati Chitroda    6 年前

    在需要的时候尝试关闭和打开数据库,现在只需在checkDataBase()的代码下面添加注释,它就可以像charm一样工作。。。

    mDB.close();