我有 PhoneGap 应用程序在 Android 中运行。当应用程序启动时,它会将大约 500 行插入到 SQL 中。表有 10 列。数据不是很多,我在文本文件中有一个 JSON,它的大小约为 120 kB。我认为这根本不会触及任何限制,但可能存在一些我不知道的限制,或者可能是 Android 中的错误,因为同一个应用程序在某些版本的 Android (2.2) 上运行没有问题,但立即崩溃或者在其他版本的 Android(1.6、2.1、一些 2.3 可能更多...)上使用 SQL 数据库时几分钟内
这是我用来填充在 Android 1.6 上崩溃的数据库的代码:
db = window.openDatabase("db", "1.0", "Description", 1000000);
$.get('db/app_data.dat',function(result){
var data = $.parseJSON(result);
try {
db.transaction(function(tx){
$.each(data.items, function(i, v){
try {
tx.executeSql('INSERT INTO table(c1,c2,c3, ...) VALUES (?,?,?, ...)',[v.c1, v.c2, v.c3, ...]);
} catch(e) {
alert(e.message);
}
});
});
} catch(e) {
alert(e.message);
return;
}
});
有人可以帮我吗?有什么我不知道的限制吗?还是我在 SQL 数据库中插入数据时做错了什么?
编辑:
这是 LogCat 的输出,我认为这些是应用程序崩溃时日志中的一些重要行。但是,我对Java和Android没有更深入的了解:
WARN/dalvikvm(1525): ReferenceTable overflow (max=512)
WARN/dalvikvm(1525): Last 10 entries in JNI local reference table:
WARN/dalvikvm(1525): 502: 0x4375cbb8 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 503: 0x4374c9a0 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 504: 0x4377c5c0 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 505: 0x437c3040 cls=Ljava/lang/String; (36 bytes)
WARN/dalvikvm(1525): 506: 0x43760bd8 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 507: 0x437625e8 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 508: 0x43762608 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 509: 0x43762628 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 510: 0x43759178 cls=Ljava/lang/String; (28 bytes)
WARN/dalvikvm(1525): 511: 0x43766808 cls=Landroid/webkit/WebViewCore; (116 bytes)
ERROR/dalvikvm(1525): Failed adding to JNI local ref table (has 512 entries)
INFO/dalvikvm(1525): "WebViewCoreThread" prio=5 tid=15 RUNNABLE
INFO/dalvikvm(1525): | group="main" sCount=0 dsCount=0 s=N obj=0x437668a0 self=0x1b0bd0
INFO/dalvikvm(1525): | sysTid=1532 nice=0 sched=0/0 handle=1772784
INFO/dalvikvm(1525): at android.webkit.LoadListener.nativeFinished(Native Method)
INFO/dalvikvm(1525): at android.webkit.LoadListener.tearDown(LoadListener.java:1076)
INFO/dalvikvm(1525): at android.webkit.LoadListener.handleEndData(LoadListener.java:642)
INFO/dalvikvm(1525): at android.webkit.LoadListener.handleMessage(LoadListener.java:203)
INFO/dalvikvm(1525): at android.os.Handler.dispatchMessage(Handler.java:99)
INFO/dalvikvm(1525): at android.os.Looper.loop(Looper.java:123)
INFO/dalvikvm(1525): at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:471)
INFO/dalvikvm(1525): at java.lang.Thread.run(Thread.java:1060)
ERROR/dalvikvm(1525): VM aborting
DEBUG/Zygote(30): Process 1525 terminated by signal (11)
最佳答案
Phobos 的回答有一些相关信息,但不包括它如何适用于您的问题或如何解决您的特定问题。我在通过使用 addJavascriptInterface 绑定(bind)到 webview 上下文的对象调用 java 的 android javascript 中进行一些性能测试时遇到了类似的问题。虽然我没有明确使用 JNI,但显然在幕后,绑定(bind)接口(interface)使用 JNI 来编码数据——我收到了一个类似于你的错误和堆栈跟踪。显然,webDB 或 localStorage 或您在那里所做的任何事情也在幕后使用 JNI。
根据 Phobos 链接的信息,当您使用 JNI 时,您可以在范围内拥有的引用数量是有限的。对于间接使用 JNI 的 javascript,似乎必须根据 javascript 范围保留引用。看看你的代码,我不确定你在做什么来超过限制,但看起来它可能是你在整个交易中进行的调用次数,或者你的值数组最终有超过 512 个元素。如果您需要保持事务完整性并且您确实有超过 500 个操作,那么您可能就不走运了。但是我怀疑您应该能够找到一种方法来避免 512 限制,方法是重写代码以在 tx.executeSql
调用范围之外构建查询字符串。
也许您可以重写代码来构建查询字符串,然后在匿名函数包装器中实际调用 tx.executeSql
?您可能需要构建包含值的字符串,而不是使用 'INSERT INTO table() VALUES()',[]
语法...正如我上面所说,如果您有超过 500 个操作交易,您可能仍然会遇到麻烦,但值得一试!
附言作为引用,这里是我的代码的一个版本,它在修复时崩溃了:
var test = function() {
var a = "a";
for(i=0;i<1000;i++) {
boundJavaObj.test(a);
}
}
test() 崩溃并出现如下错误:
03-28 10:57:45.634:W/dalvikvm(21294):ReferenceTable 溢出(最大=512)
var test2 = function() {
var a = "a";
for(i=0;i<1000;i++) {
(function(){boundJavaObj.test(a);})();
}
}
test2() 不会崩溃。
关于javascript - 为什么 PhoneGap Android 应用程序在将大量数据插入 SQL 时崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6291692/