小编典典

在将大量数据插入SQL时,为什么PhoneGap Android应用程序崩溃?

sql

我有在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)

阅读 205

收藏
2021-03-23

共1个答案

小编典典

Phobos的答案包含一些相关信息,但不包括它如何应用于您的问题或如何解决您的特定问题。我在android
javascript中进行一些性能测试时遇到了类似的问题,该测试通过使用addJavascriptInterface绑定到webview上下文中的对象调用java。尽管我没有明确地使用JNI,但显然在绑定的幕后,使用JNI来整理数据的绑定接口-我遇到了与您类似的错误和堆栈跟踪。显然,webDB或localStorage或您在此处所做的任何事情都在幕后使用JNI。

根据Phobos链接的信息,使用JNI时,作用域中的引用数有一个有限的限制。对于间接使用JNI的javascript,似乎必须根据javascript范围保留引用。查看您的代码,我不确定您要超出限制的确切方式,但看起来可能是您在整个事务中进行的调用次数,或者值数组最终包含超过512个元素。如果您需要维护事务的完整性,并且确实有500多次操作,那么您可能会很不幸。但是我怀疑您应该能够通过重写代码以在tx.executeSql调用范围之外建立查询字符串来找到避免512限制的方法。

也许您可以重写代码以构建查询字符串,然后tx.executeSql在匿名函数包装器中实际调用?您可能需要构建包含值的字符串而不是使用'INSERT INTO table() VALUES()',[]语法…如上所述,如果一个事务中有500个以上的操作,您仍然可能会遇到麻烦,但是值得尝试!

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()不会崩溃。

2021-03-23