我正在使用SQLLite作为Android的基于phonegap的应用程序。我面临的问题是,只要应用程序处于打开状态,我就可以获取我存储在local.db文件中的任何数据。 例如,我有一个设置功能,用户可以保存他/她的设置,然后进入db.Now我面临的问题是,我无法获取用户在应用程序关闭后保存的数据,I只要应用程序处于打开状态,就可以获取数据。 所以问题是数据库不是持久的。任何人都可以告诉如何在应用程序关闭时将数据存储在内存中吗?
这是我的mainActivity文件
public class Demo extends CordovaActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init();
super.loadUrl(Config.getStartUrl());
try {
String pName = this.getClass().getPackage().getName();
this.copy("Databases.db", "/data/data/" + pName + "/app_database/");
this.copy("0000000000000001.db", "/data/data/" + pName
+ "/app_database/file__0/");
} catch (IOException e) {
e.printStackTrace();
}
}
void copy(String file, String folder) throws IOException {
File CheckDirectory;
CheckDirectory = new File(folder);
if (!CheckDirectory.exists()) {
CheckDirectory.mkdir();
InputStream in = getApplicationContext().getAssets().open(file);
OutputStream out = new FileOutputStream(folder + file);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
in.close();
out.close();
}
}
}
这些是我给出的权限: -
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
将复制代码移动到 NigelK 所提及的if条件后完成了诀窍。但卸载构建并创建新构建后,给出了以下错误: -
01-10 16:11:34.466: E/SQLiteLog(29253): (1) no such table: CacheGroups
01-10 16:11:34.466: D/WebKit(29253): ERROR:
01-10 16:11:34.466: D/WebKit(29253): Application Cache Storage: failed to execute statement "DELETE FROM CacheGroups" error "no such table: CacheGroups"
01-10 16:11:34.466: D/WebKit(29253): external/webkit/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp(558) : bool WebCore::ApplicationCacheStorage::executeSQLCommand(const WTF::String&)
01-10 16:11:34.466: E/SQLiteLog(29253): (1) no such table: Caches
01-10 16:11:34.466: D/WebKit(29253): ERROR:
01-10 16:11:34.466: D/WebKit(29253): Application Cache Storage: failed to execute statement "DELETE FROM Caches" error "no such table: Caches"
01-10 16:11:34.466: D/WebKit(29253): external/webkit/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp(558) : bool WebCore::ApplicationCacheStorage::executeSQLCommand(const WTF::String&)
01-10 16:11:34.466: E/SQLiteLog(29253): (1) no such table: Origins
01-10 16:11:34.466: D/WebKit(29253): ERROR:
01-10 16:11:34.466: D/WebKit(29253): Application Cache Storage: failed to execute statement "DELETE FROM Origins" error "no such table: Origins"
01-10 16:11:34.466: D/WebKit(29253): external/webkit/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp(558) : bool WebCore::ApplicationCacheStorage::executeSQLCommand(const WTF::String&)
01-10 16:11:34.476: E/SQLiteLog(29253): (1) no such table: DeletedCacheResources
关于如何处理这个问题的任何想法?
答案 0 :(得分:2)
您的数据库是持久的,问题是每次您的应用程序启动时,onCreate()中对copy()方法的调用会再次使用Assets中保存的副本覆盖数据库。我想你只想制作一次这样的副本。一种方法是仅在目标目录尚不存在时才执行复制:
if (!CheckDirectory.exists()) {
CheckDirectory.mkdir();
...move the copy code inside this if block
}
或者您可以在共享首选项中存储标志,并在制作副本时将其设置为true。在onCreate中,如果该标志为false,则仅执行副本。
编辑:
使用共享偏好标记:
on onCreate:
SharedPreferences sp = getSharedPreferences("MYPREFS", Activity.MODE_PRIVATE);
//If no shared prefs exist, e.g. first install, it doesn't matter - the following will return false as a default
Boolean database_copied = sp.getBoolean("database_copied", false);
if (!database_copied)
{
try {
String pName = this.getClass().getPackage().getName();
this.copy("Databases.db", "/data/data/" + pName + "/app_database/");
this.copy("0000000000000001.db", "/data/data/" + pName
+ "/app_database/file__0/");
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("database_copied", true);
editor.apply();
} catch (IOException e) {
e.printStackTrace();
}
}
答案 1 :(得分:0)
只需创建一个空白数据库并将其替换为新资产DB ..
Thread getData = new Thread() {
public void run() {
Data.qh = new QueryHandler(mContext); // for creating a blank DB
DB_PATH = getDatabasePath("htest.sqlite").getAbsolutePath(); // get the path of blank DB
copyDataBase(mContext);
};
};
void copyDataBase(Context mContext) {
try {
String outFileName = DB_PATH;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
InputStream myInput = mContext.getAssets().open("htest.sqlite");
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myInput.close();
myOutput.flush();
myOutput.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
答案 2 :(得分:0)
下面是示例代码,这是在Javascript调用的html页面中实现的
function onDeviceReady()
{
var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
db.transaction(populateDB, errorCB, successCB);
}
然后我们必须在Table中填充数据,调用方法
function populateDB(tx)
{
var id=$('#id').val();
var firstname=$('#firstname').val();
tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, firstname)');
tx.executeSql('INSERT INTO DEMO (id, firstname) VALUES (?, ?)', [id, firstname]);
}
要保存数据,请执行以下任何事件
<button class="button" id="clickMe" onclick="onDeviceReady();" >Save</button>