Форум программистов, компьютерный форум, киберфорум
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
semiromid
7 / 7 / 2
Регистрация: 28.08.2014
Сообщений: 179
#1

AsyncTask и SQLite - Программирование Android

08.04.2015, 14:57. Просмотров 697. Ответов 11
Метки нет (Все метки)

Здравствуйте! У меня в приложении есть БД SQLite, при нажатие на кнопку загрузки, приложение начинает в базу вносить записи.
Структура базы :
1.таблица-одна, колонка - одна
2.Кол-во записей : 20 000
3.Формат записи: String до 10 символов.

Метод добавления : через бэкграунд, фоновый поток, используя наследования класса "AsyncTask"


Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class MyTask extends AsyncTask<Void, Integer, Void> {
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Info.setText("Начали ");
        }
 
        @Override
        protected Void doInBackground(Void... params) {
            int counter = 0;
            try {           
                for(int i=0; i<20000;i++){      
                                getFloor(counter);
                    publishProgress(++counter);
                    }   
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }
 
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            Info.setText("Позиция : " + values[0]);
            horizontalprogress.setProgress(values[0]);
        }
        
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Info.setText("Загрузили");  
        }
        
        
        private void getFloor(int floor) throws InterruptedException {
               // Метод 1: INSERT через класс CONTENTVALUE
                   ContentValues cv = new ContentValues();
                   cv.put("time", "Hello "+floor);
                  // вызываем метод вставки
                  Asqdb1.insert("alarm_table",null, cv);
        }
        
        
    }
При занесения записей в базу, уходит около 10-20 минут. Подскажите пожалуйста, нормальная ли это ситуация, когда так долго происходит добавления записей в БД?
Я понимаю что в фоновом потоке задачи выполняются медленнее. Но всё таки, мне кажется что то слишком долго.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.04.2015, 14:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос AsyncTask и SQLite (Программирование Android):

AsyncTask - Программирование Android
Использую AsyncTasc class MyT extends AsyncTask&lt;Void, Void, Void&gt; { @Override protected Void doInBackground(Void......

AsyncTask - Программирование Android
Здравствуйте, при использовании двух одинаковых методов получается разный результат. AsyncTask в одном случае успешно передает данные в...

AsyncTask и get() - Программирование Android
Создаю асинхронный процесс, где в onPreExecute() запускаю анимированный ProgressDialog. После выполнения задачи нужно выполнить действия....

AsyncTask - Программирование Android
Привет. Знаю, что в AsyncTask doInBackground() обращатся к компонентам UI нельзя. Когда я пытаюсь обновить вывод (в EditText) в...

AsyncTask тормозит - Программирование Android
Подскажите пожалуйста, делалю загрузку данных с сервера через asyncTask и возвращаются результат, а дальше делаю обработку этих данных во...

Работа с AsyncTask - Программирование Android
Попробовал использовать AsyncTask и возник вопрос. У меня есть несколько ф-й, которые парсят текстовые файлы и заполняют таблицы БД. ...

11
Pablito
2525 / 2004 / 624
Регистрация: 12.05.2014
Сообщений: 7,030
Завершенные тесты: 1
08.04.2015, 15:01 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
я бы добавлял не по 1 записи, а по 100 например
и прогресс тоже обновлял не после каждой записи
1
androbro
326 / 287 / 61
Регистрация: 17.10.2014
Сообщений: 854
08.04.2015, 16:08 #3
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
semiromid,
Цитата Сообщение от semiromid Посмотреть сообщение
ContentValues cv = new ContentValues();
мб не надо 20000 раз создавать новый, хватит и одного экземпляра.
1
CoolMind
419 / 402 / 65
Регистрация: 06.10.2012
Сообщений: 1,727
08.04.2015, 16:18 #4
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
semiromid, товарищ, это архинеправильно.
Во-первых, непонятен смысл переменной counter, если есть i.
Во-вторых, пользователь не увидит общее количество записей, только лишь текущую. Соответственно, непонятно, как вы будете выводить процент выполнения.
В-третьих, как уже правильно сообщили, вставка по одной записи годится разве что для 10 записей. В противном случае надо читать мануалы. Требуется использовать транзакции и вставлять циклом все записи.
1
Netscape
374 / 361 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
08.04.2015, 17:33 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Самая примитивная оптимизация InsertHelper + Transaction

http://schleicher.ru/blog/583.html
1
semiromid
7 / 7 / 2
Регистрация: 28.08.2014
Сообщений: 179
09.04.2015, 01:38  [ТС] #6
Паблито,

я бы добавлял не по 1 записи, а по 100 например
и прогресс тоже обновлял не после каждой записи
А как?
Нужно некий пул создавать?

Добавлено через 1 час 25 минут
CoolMind,
publishProgress(++counter); - выводит процент выполнения

В-третьих, как уже правильно сообщили, вставка по одной записи годится разве что для 10 записей. В противном случае надо читать мануалы. Требуется использовать транзакции и вставлять циклом все записи.
Циклом вставлять записи? - for цикл медленный ( Нужно что то другое
Может лучше вставлять кусками типо так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
                  cv.put("time", "Hello "+floor);
                  // вызываем метод вставки
                  Asqdb1.insert("alarm_table",null, cv);
 
                  cv.put("time", "Hello "+floor);
                  // вызываем метод вставки
                  Asqdb1.insert("alarm_table",null, cv);
 
                  cv.put("time", "Hello "+floor);
                  // вызываем метод вставки
                  Asqdb1.insert("alarm_table",null, cv);
 
                //и.т.д  до 100 например
Нормально так будет?
Что то мне подсказывает что, нет( А как лучше тогда?

Спасибо.
0
CoolMind
419 / 402 / 65
Регистрация: 06.10.2012
Сообщений: 1,727
09.04.2015, 11:00 #7
semiromid, пожалуйста.
Почитайте, например, здесь: http://habrahabr.ru/post/205620/ и внутри тоже пройдите по ссылке.

Добавлено через 3 минуты
Netscape предлагает тоже хороший вариант, там правильно указано про блок finally при завершении транзакции. Некоторые программисты про него забывают.
1
semiromid
7 / 7 / 2
Регистрация: 28.08.2014
Сообщений: 179
09.04.2015, 13:24  [ТС] #8
CoolMind,
Спасибо за ссылки.
Но я уже реализовал все, работает в десятки раз быстрее. Было 15-20 минут загрузки, стало 13 секунд.

Мне бы еще хотелось бы услышать ответ на мой вопрос.

Циклом вставлять записи? - for цикл медленный ( Нужно что то другое
Может лучше вставлять кусками типо так:
cv.put("time", "Hello "+floor);
// вызываем метод вставки
Asqdb1.insert("alarm_table",null, cv);

cv.put("time", "Hello "+floor);
// вызываем метод вставки
Asqdb1.insert("alarm_table",null, cv);

cv.put("time", "Hello "+floor);
// вызываем метод вставки
Asqdb1.insert("alarm_table",null, cv);

//и.т.д до 100 например
Нормально так будет?
Что то мне подсказывает что, нет( А как лучше тогда?

Спасибо.
0
CoolMind
419 / 402 / 65
Регистрация: 06.10.2012
Сообщений: 1,727
09.04.2015, 13:48 #9
semiromid, пожалуйста.
Если вы реализовали, то зачем вам ответ на этот вопрос? Кстати, вопрос-то в чём? В медленности цикла for? Нет, он такое же, как и любые другие циклы. Разве что foreach быстрее. Заменять for на куски кода, делающие то же самое, но без for, бессмысленно и даже вредно.
1
semiromid
7 / 7 / 2
Регистрация: 28.08.2014
Сообщений: 179
09.04.2015, 14:06  [ТС] #10
CoolMind,
Спасибо.

Но мне хотелось бы знать, как вставлять в базу данных информацию неким объемом за один раз.
Или как правильно вставлять информацию, таким способом.
Правильно ли я в примере показываю как её вставлять, или нет?

Добавлено через 9 минут
CoolMind,
Может быть другими словами, как вставить 100 записей в одну и ту же колонку БД, одним insert?
0
CoolMind
419 / 402 / 65
Регистрация: 06.10.2012
Сообщений: 1,727
09.04.2015, 15:41 #11
semiromid, насколько я знаю, SQL-запросы позволяют вставку либо по одной записи за раз, либо вставку данных из запроса (множество за раз). Запросом обычно вытягиваются данные из существующих таблиц. Таким образом, если данные для БД являются новыми (не извлекаются из другой таблицы этой же БД), другого способа не придумать.
1
fgtmenow
75 / 75 / 7
Регистрация: 29.03.2012
Сообщений: 254
10.04.2015, 01:43 #12
советую почитать про sql очень внимательно и вдумчиво.

Insert - это вставка одной строки в таблицу,
для закрепления изменений используется commit

Ты можешь сделать 10 раз insert, и 1 раз закрепить все одним commit'ом. Надеюсь смысл ты понял.

При том в больших вставках - это рекомендуемое решение. Например при вставке 20000 делать коммит после 5000 записей
1
10.04.2015, 01:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.04.2015, 01:43
Привет! Вот еще темы с ответами:

AsyncTask+CheckBox - Программирование Android
Здравствуйте, интересует вопрос нужно в функцию AsyncTask послать несколько строк, в зависимости какие Чекбоксы чекнуты. Ну например: ...

AsyncTask и Jsoup - Программирование Android
Не работает вот такой код: package com.example.projecta; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import...

Отмена AsyncTask - Программирование Android
Привет. Есть такой код: @Override protected Void doInBackground(Void... params) { try { Interpret(Source.get()); }...

MainActivity AsyncTask - Программирование Android
Добрый вечер. Ребята тут небольшая проблема. Мне нужно Заполнить NavigatorDrawer (из базы). Почему когда я пытаюсь в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru