【问题标题】:data inserted into external sqlite database but not saving in android studio数据插入外部 sqlite 数据库但未保存在 android studio
【发布时间】:2018-12-21 15:13:22
【问题描述】:

我使用的是外部 sqlite 数据库,而不是在我的 android studio 项目中创建一个,因为该数据库将包含一些已经填充的数据在里面。但我还必须插入更多数据。 当我插入任何新数据时,它会显示新数据,但是当我关闭我的 android 应用程序并再次打开以查看数据时,通过应用程序新插入的数据以某种方式删除,只有预填充的数据是显示。

我正在使用用于 sqlite 的 DB 浏览器来创建外部 sqlite 数据库并在其中预填充一些数据。在我的 android studio 项目中,我将这个数据库添加到我的 assets 文件夹中,并实现了 SQLiteOpenHelper 类来访问这个数据库。从数据库表中读取数据是成功的。现在,当我插入新数据时,我也可以临时读取新数据。暂时从某种意义上说,在我关闭我的应用程序后,新数据会丢失。

我的外部 sqlite 数据库的表:

CREATE TABLE `table_name` (
`Id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`Content`   TEXT NOT NULL
);

SQLiteOpenHelper 类:

public class ProcessExternalDBHelper {
private static final String DATABASE_NAME = "database_name.db";
private static final int DATABASE_VERSION = 1;
private static String DATABASE_PATH = "";

private static final String DATABASE_TABLE = "table_name";
private static final String KEY_ROWID = "Id";
private static final String KEY_CONTENT = "Content";

private ExternalDbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;

private static class ExternalDbHelper extends SQLiteOpenHelper {

    public ExternalDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        if (Build.VERSION.SDK_INT >= 17) {
            DATABASE_PATH = context.getApplicationInfo().dataDir + 
"/databases/";
        } else {
            DATABASE_PATH = "/data/data/" + context.getPackageName() + 
"/databases/";
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int 
newVersion) {

    }
}

public ProcessExternalDBHelper(Context context) {
    ourContext = context;
}
//for reading
public ProcessExternalDBHelper openRead() throws SQLException {
    ourHelper = new ExternalDbHelper(ourContext);
    ourDatabase = ourHelper.getReadableDatabase();
    return this;
}
//for writing
public ProcessExternalDBHelper openWrite() throws SQLException{
    ourHelper = new ExternalDbHelper(ourContext);
    ourDatabase = ourHelper.getWritableDatabase();
    return this;
}

public void close() {
    if (ourHelper != null) {
        ourHelper.close();
    }
}

//Create database in activity
public void createDatabase() throws IOException {
    createDB();
}
//Create db if not exists
private void createDB() {
    boolean dbExists = checkDatabase();
    if (!dbExists) {
        openRead();             
        try {
            this.close();
            copyDatabase();
        } catch (IOException ie) {
            throw new Error("Error copying database");
        }
    }
}

private boolean checkDatabase() {
    boolean checkDB = false;
    try {
        String myPath = DATABASE_PATH + DATABASE_NAME;
        File dbfile = new File(myPath);
        checkDB = dbfile.exists();
    } catch (SQLiteException e) {

    }
    return checkDB;
}

private void copyDatabase() throws IOException {
    InputStream myInput = null;
    OutputStream myOutput = null;
    String outFileName = DATABASE_PATH + DATABASE_NAME;

    try {
        myInput = ourContext.getAssets().open(DATABASE_NAME);
        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();
    } catch (IOException ie) {
        throw new Error("Copydatabase() error");
    }
}
//To show all available contents in my database
public List<Model> findallContents() {
    List<Model> mContents = new ArrayList<>();

    String[] columns = new String[]{KEY_CONTENT};
    Cursor cursor = ourDatabase.query(DATABASE_TABLE, columns, null, null, 
null, null, null);
    int iContent = cursor.getColumnIndex(KEY_CONTENT);

    for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) 
    {
        Model model= new Model();
        model.setContent(cursor.getString(iContent));

        mContents.add(model);
    }

    cursor.close();
    return mContents;
}

public void addContent(String content) {
    ContentValues contentValues = new ContentValues();
    contentValues.put(KEY_CONTENT, content);

    ourDatabase.insert(DATABASE_TABLE, null, contentValues);
    ourDatabase.close();
}

}

我的 Model.java 类:

public class Model {
    private String mContent;

    public String getContent() {
    return mContent;
    }

    public void setContent(String content) {
        this.mContent = content;
    }
}

最后是我读写数据的活动类:

public class MainActivity extends AppCompatActivity {

private EditText editText_Content;
private ImageButton imageButton_Save;
private List<Model> mContentsArrayList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ProcessExternalDBHelper myDbHelper = new ProcessExternalDBHelper(this);
    try {
        myDbHelper.createDatabase();
    } catch (IOException ioe) {
        throw new Error("Unable to CREATE DATABASE");
    } finally {
        myDbHelper.close();
    }

    initialize();

    GetContents();

    imageButton_Save.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!(editText_Content.getText().toString().trim().isEmpty())) 
            {
                SaveContents();
            } 
        }
    });
}

private void initialize() {
    editText_Content = findViewById(R.id.editText_contents);
    imageButton_Save = findViewById(R.id.imageButton_save);

    mContentsArrayList = new ArrayList<>();
}
//GetContents and show them later in my RecyclerView
private void GetContents() {
    try {
        mContentsArrayList.clear();
        ProcessExternalDBHelper autoProcess = new 
    ProcessExternalDBHelper(this);
        autoProcess.openRead();
        mContentsArrayList.addAll(autoProcess.findallContents();
        autoProcess.close();
    } catch (Exception e) {

    }
}
//For saving content into database    
private void SaveContents() {
    String content = editText_Content.getText().toString();

    try {
        ProcessExternalDBHelper autoProcess = new 
ProcessExternalDBHelper(this);
        autoProcess.openWrite();   //for writing into database
        autoProcess.addContent(content);
        autoProcess.close();
        editText_Content.getText().clear();
    } catch (Exception e) {

    }
}

}

最后我正在使用 DB Browser for Sqlite (ver 3.10.1), android studio (ver 3.0.1), minSdkVersion 19.

我希望新插入到数据库中的数据能够被保存并在以后看到,即使我关闭我的应用程序并稍后重新启动应用程序也是如此。 谢谢!

【问题讨论】:

    标签: java android sqlite


    【解决方案1】:

    您的问题是 DATABASE_PATH 没有被重置,因此在调用 createDatabase 时为空。

    因此检查数据库是否存在找不到数据库(它纯粹是在文件系统的最高级别查找文件database_db.db,因此该文件不存在) 并且数据库被复制,覆盖了保存数据的数据库。

    我建议进行以下更改:-

    private boolean checkDatabase() {
        File dbfile = new File(ourContext.getDatabasePath(DATABASE_NAME).getPath());
        if ( dbfile.exists()) return true;
        File dbdir = dbfile.getParentFile();
        if (!dbdir.exists()) {
            dbdir.mkdirs();
        }
        return false;
    }
    
    • 这样做的好处是,如果数据库目录不存在,它将被创建,并且它仅依赖于路径的数据库名称。
    • 也不需要 try/catch 构造。

    以及可选的:-

    private void copyDatabase() throws IOException {
        InputStream myInput = null;
        OutputStream myOutput = null;
        String outFileName = ourContext.getDatabasePath(DATABASE_NAME).getPath(); //<<<<<<<<<< CHANGED
    
        try {
            myInput = ourContext.getAssets().open(DATABASE_NAME);
            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();
        } catch (IOException ie) {
            throw new Error("Copydatabase() error");
        }
    }
    
    • 请注意,如果应用了上述方法,则无需进行 SDK 版本检查,因为 getDatabasePath 方法获取了正确的路径。

    【讨论】:

    • 是的,我也在 createDatabase() 中通过初始化我的 DATABASE_PATH 进行了检查。我真的要感谢你帮助我理解我的错误并展示更有效的方法。成功了!!!
    猜你喜欢
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多