数据已插入外部sqlite数据库中,但未保存在android studio中

时间:2018-12-21 03:23:25

标签: java android sqlite

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

我正在使用用于sqlite的数据库浏览器来创建外部sqlite数据库,并在该数据库中预先填充一些数据。在我的android studio项目中,我将此数据库添加到了我的资产文件夹中,并实现了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) {

    }
}

}

最后,我将数据库浏览器用于Sqlite(3.10.1版),Android Studio(3.0.1版),minSdkVersion 19。

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

1 个答案:

答案 0 :(得分: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方法会获取正确的路径。