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

标签 javascript android sql crash cordova

我有 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/

相关文章:

javascript - window.name在IE中的作用范围是什么?

android - 在我的墙上时不显示 Facebook 分享描述

java - 来自 HTTP POST 请求的 500 内部错误

sql - 具有重复电子邮件 ID 的不同行的计数

javascript - 如何在javascript中获取数组中的最小元素?

javascript - 使这段 JS 代码不引人注目。为未知 id 编写事件监听器

javascript - 将鼠标悬停在类 "thing"、 "bn1"、 "bn2"等上时编辑类 "bn3"的 css?

android - NavBar 下方的 BottomNavigationBar

sql - 让 Doctrine 在 INSERT INTO 期间跳过只读字段/列

SQL Server 2008 - 名称 "Procedures"是否保留?