Почему приложение Android PhoneGap разбивается, вставляя кучу данных в SQL?

У меня есть приложение PhoneGap, работающее на Android. Когда приложение запускается, оно вставляет примерно 500 строк в SQL. Таблица содержит 10 столбцов. Это не так много данных, у меня есть текстовый файл JSON и его размер составляет около 120 кБ. Я думал, что это никак не может коснуться каких-либо ограничений, но, вероятно, есть некоторые ограничения, о которых я не знаю или, может быть, об ошибках в Android, потому что это же приложение работает на некоторых версиях Android (2.2) без проблем, но сразу же срабатывает Или в течение нескольких минут при работе с базой данных SQL в других версиях Android (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 содержит некоторую соответствующую информацию, но не включает, как это относится к вашей проблеме или как исправить вашу конкретную проблему. Я столкнулся с подобной проблемой, выполняя некоторые тесты производительности в JavaScript-андроиде, которые переходят в java через объект, связанный в контексте webview с помощью addJavascriptInterface. Хотя я явно не использую JNI, видимо, под обложками связанный интерфейс использует JNI для сортировки данных через – я получал ошибку и трассировку стека, аналогичную вашей. По-видимому, webDB или localStorage или все, что вы там делаете, также использует JNI под обложками.

Согласно информации, связанной с Фобосом, существует ограниченный предел количества ссылок, которые вы можете иметь в области, когда вы используете JNI. В случае javascript, который косвенно использует JNI, кажется, что ссылки должны храниться на основе области javascript. Глядя на ваш код, я не уверен, что вы делаете, чтобы превысить лимит, но похоже, что это может быть либо количество вызовов, которые вы совершаете в транзакции в целом, либо массивы значений в итоге имеют более 512 элементов. Если вам нужно сохранить целостность транзакций, и у вас действительно более 500 операций, вам может быть не повезло. Однако я подозреваю, что вы должны найти способ избежать ограничения 512, переписывая свой код, чтобы создать строку запроса за пределами области вызова tx.executeSql .

Может быть, вы могли бы переписать код для создания строк запроса, а затем на самом деле вызвать 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 () не сбой.

Возможно, вам нужна рекурсивная функция обратного вызова:

 //too many insert statements var sqlits= ["INSERT INTO ...", .. .. .. ,"INSERT INTO ..."]; function populate(){ db.transaction(function(tx){ if(sqlits.length > 0){ sql=sqlits.shift(); tx.executeSql(sql); }else{ alert('End'); } return true; },function(tx,err){ console.log("SQL Error: "+err); },populate); }; populate(); 

ОК. Нашел ответ. Это ограничение в 512 локальных ссылок. Что вам нужно сделать, это преобразовать их в глобальные ссылки с помощью NewGlobalRef () или очистить местных жителей вскоре после их создания, если они не нужны. Однако изменение их на глобальные ссылки приведет к утечке памяти.

Ознакомьтесь с этой веткой для получения дополнительной информации об этой известной проблеме.

Intereting Posts
Как найти скорость передачи данных в сети GPRS / 3G в android? Интеграция WeChat в мое приложение для Android для входа в систему Отображение индикатора выполнения в диалоговом окне предупреждения Почему LogCat показывает все элементы как предупреждения (оранжевые)? Какие намерения поддерживает приложение Android для Android Как рисовать половину круга в андроиде Как получить идентификатор самого верхнего действия? Как предотвратить мигание панели инструментов и навигационной панели при переходе активности совместного просмотра? Как загрузить плитки osmdroid в конце пользователя? Как сделать паузу в течение 5 секунд, прежде чем рисовать следующую вещь на Android? Почему в проекте build.gradle для Android есть обычная «чистая» задача? Intellij IDEA разбился и теперь выдает ошибку Потоковое аудио с URL-адреса в Android с помощью MediaPlayer? ViewPager + FragmentStatePagerAdapter: ViewPager перестает работать при изменении ориентации экрана Как отправить запрос на HTTP-запрос POST на сервер