我有在Android中运行的PhoneGap应用。应用启动时,它将在SQL中插入大约500行。表有10列。它的数据不是很多,我在文本文件中有一个JSON,它的大小约为120 kB。我以为这根本无法解决任何限制,但是可能存在一些我不了解的限制,或者可能是Android中的错误,因为同一应用程序可以在某些版本的Android(2.2)上正常运行,但立即崩溃或在其他版本的Android上使用SQL数据库(几分钟,1.6、2.1,大约2.3甚至更多……)时,也可能需要几分钟
这是我用来填充在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的答案包含一些相关信息,但不包括它如何应用于您的问题或如何解决您的特定问题。我在android javascript中进行一些性能测试时遇到了类似的问题,该测试通过使用addJavascriptInterface绑定到webview上下文中的对象调用java。尽管我没有明确地使用JNI,但显然在绑定的幕后,使用JNI来整理数据的绑定接口-我遇到了与您类似的错误和堆栈跟踪。显然,webDB或localStorage或您在此处所做的任何事情都在幕后使用JNI。
根据Phobos链接的信息,使用JNI时,作用域中的引用数有一个有限的限制。对于间接使用JNI的javascript,似乎必须根据javascript范围保留引用。查看您的代码,我不确定您要超出限制的确切方式,但看起来可能是您在整个事务中进行的调用次数,或者值数组最终包含超过512个元素。如果您需要维护事务的完整性,并且确实有500多次操作,那么您可能会很不幸。但是我怀疑您应该能够通过重写代码以在tx.executeSql调用范围之外建立查询字符串来找到避免512限制的方法。
tx.executeSql
也许您可以重写代码以构建查询字符串,然后tx.executeSql在匿名函数包装器中实际调用?您可能需要构建包含值的字符串而不是使用'INSERT INTO table() VALUES()',[]语法…如上所述,如果一个事务中有500个以上的操作,您仍然可能会遇到麻烦,但是值得尝试!
'INSERT INTO table() VALUES()',[]
PS供参考,以下是我的代码版本及其修复程序崩溃:
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 overflow (max=512)
var test2 = function() { var a = "a"; for(i=0;i<1000;i++) { (function(){boundJavaObj.test(a);})(); } }
test2()不会崩溃。