- Полнотекстовый поиск в Android
- Подходы к реализации поиска в мобильном приложении
- Подготовка данных
- Наполнение базы данных
- Базовый вариант
- Добавляем акценты
- Резюме
- How to View and Locate SQLite Database in Android Studio?
- Step by Step Procedures
- Правильная работа с БД в Android
- Android SearchView in Room Database
- Step by Step Implementation
Полнотекстовый поиск в Android
В мобильных приложениях очень востребована функция поиска. И если в небольших продуктах ею можно пренебречь, то в приложениях, которые предоставляют доступ к большому количеству информации, без поиска не обойтись. Сегодня я расскажу, как правильно реализовать эту функцию в программах под Android.
Подходы к реализации поиска в мобильном приложении
- Поиск как фильтр данных
Обычно это выглядит как строка поиска над каким-нибудь списком. То есть мы просто фильтруем уже готовые данные.
Серверный поиск
В этом случае мы отдаём всю реализацию на откуп серверу, а приложение выступает в роли тонкого клиента, от которого требуется лишь показать данные в нужном виде.
Комплексный поиск
- приложение содержит в себе большое количество данных разного типа;
- приложение работает оффлайн;
- поиск нужен как единая точка доступа к разделам/контенту приложения.
В последнем случае на помощь приходит встроенный в SQLite полнотекстовый поиск (Full-text search). С его помощью можно очень быстро находить совпадения в большом объёме информации, что позволяет нам делать несколько запросов в разные таблицы без снижения производительности.
Рассмотрим реализацию такого поиска на конкретном примере.
Подготовка данных
Допустим, нам необходимо реализовать приложение, которое показывает список фильмов с сайта themoviedb.org. Для упрощения (чтобы не ходить в сеть), возьмём список фильмов и сформируем из него JSON-файл, положим его в assets и локально будем наполнять нашу базу данных.
Пример структуры JSON-файла:
Наполнение базы данных
Для реализации полнотекстового поиска в SQLite используются виртуальные таблицы. Внешне они выглядят как обычные таблицы SQLite, но при любом обращении к ним выполняется некая закулисная работа.
Виртуальные таблицы позволяют нам ускорить поиск. Но, помимо преимуществ, у них есть и недостатки:
- нельзя создать триггер на виртуальной таблице;
- нельзя выполнять команды ALTER TABLE и ADD COLUMN для виртуальной таблицы;
- каждый столбец в виртуальной таблице индексируется, а это значит, что могут впустую тратиться ресурсы на индексацию столбцов, которые не должны участвовать в поиске.
Для решения последней проблемы можно использовать дополнительные таблицы, которые будут содержать часть информации, а в виртуальной таблице хранить ссылки на элементы обычной таблицы.
Создание таблицы немного отличается от стандартного, у нас появились ключевые слова VIRTUAL и fts4 :
Наполнение же ничем не отличается от обычного:
Базовый вариант
При выполнении запроса используется ключевое слово MATCH вместо LIKE :
Для реализация обработки ввода текста в интерфейсе будем использовать RxJava :
Получился базовый вариант поиска. В первом элементе нужное слово нашлось в описании, а во втором элементе — и в заголовке, и в описании. Очевидно, что в таком виде не совсем понятно, что мы нашли. Давайте это исправим.
Добавляем акценты
Для улучшения очевидности поиска воспользуемся вспомогательной функцией SNIPPET . Она используется для отображения отформатированного фрагмента текста, в котором найдено совпадение.
- movies — название таблицы;
- Алгоритм Портера
После этого преобразования фраза «дворы и призраки» выглядит как «двор* OR призрак*».
Символ «*» означает, что поиск будет вестись по вхождению данного слова в другие слова. Оператор «OR» означает, что будут показаны результаты, которые содержат хотя бы одно слово из поисковой фразы. Смотрим:
Резюме
Полнотекстовый поиск не такой сложный, как может показаться с первого взгляда. Мы разобрали конкретный пример, который вы быстро и легко сможете реализовать у себя в проекте. Если вам нужно что-то сложнее, то стоит обратиться к документации, благо она есть и довольно хорошо написана.
Источник
How to View and Locate SQLite Database in Android Studio?
SQLite is an open-source relational database that is used to perform database operations on android devices such as storing, manipulating, or retrieving persistent data from the database. In this article, we will learn how to view and locate SQLite database in Android Studio using device file explorer.
Note: Package name is found at the top of any class e.g. in MainActivity.java class it is found at the top by the syntax.
package package_name;
Step by Step Procedures
Step 1: Open android studio project which has SQLite database connection
Open existing android studio project which has connected to SQLite database and already having some saved records.
Step 2: Connect a device
Connect external device or emulator with android studio make sure the name of the device must be shown on android studio screen.
Step 3: Search for Device File Explorer in android studio
Device file explorer can be found in the bottom-right corner of the android studio screen. Click on Device file explorer.
Step 4: Search application package name
To search your package name go to data > data> package name. Click on package name.
Step 5: Download the database
Now, select database and download database whose extension will be .sqlite, for that right-click on the database name and save file at any desired location but remember the location then click on ok in Save As dialog box.
Step 6: Download SQLite browser
Now to view the database we required SQLite browser, you can download SQLite browser from https://sqlitebrowser.org/dl/. Download a suitable SQLite browser for your device from the above link and open it.
Step 7: Search saved database file
Click on the open database this will open a dialog box choose a database file. Now go to that location where you have saved the database previously and then select the database file and click on open.
Step 8: View saved data in tables
To view data saved in the table click on Browse data, now that’s it we have completed our today’s task.
Источник
Правильная работа с БД в Android
Приветствую всех дроидеров в эти непростые для нас времена.
Честно говоря, заколебала эта шумиха о патентах, войнах и т.д., но в данной статье речь пойдет не об этом.
Я не собирался писать статью на данную тему, так как везде всего полно о работе с базой данных в Android и вроде бы все просто, но уж очень надоело получать репорты об ошибках, ошибках специфичных и связанных с БД.
Поэтому, я рассматрю пару моментов с которыми я столкнулся на практике, чтобы предостеречь людей, которым только предстоит с этим разбираться, а дальше жду ваших комментариев на тему решения указанных проблем после чего внесу изменения в пост и мы сделаем отличный туториал, который будет образцом работы с SQLite в Android не только для начинающих, но и для тех, кто уже знаком с основами и написал простые приложения.
Способы работы с БД
Существует три способа работы с данными в БД, которые сразу бросаются на ум:
1) Вы создаете пустую структуру базы данных. Пользователь работает с приложением(создает заметки, удаляет их) и база данных наполняется. Примером может служить приложение NotePad в демо-примерах developer.android.com или на вашем дроид-девайсе.
2) Вы уже имеете готовую БД, наполненную данными, которую нужно распространять с приложением, либо парсите данные из файла в assets.
3) Получать данные из сети, по мере необходимости.
Если есть какой-то еще один или два способа, то с радостью дополню данный список с вашей помощью.
Все основные туториалы расчитаны как раз на первый случай. Вы пишите запрос на создание структуры БД и выполняете этот запрос в методе onCreate() класса SQLiteOpenHelper, например так:
Примерно так. Более полный вариант класса и других составляющих можно посмотреть по ссылке внизу статьи.
Дополнительно можно переопределить методы onOpen(), getReadableDatabase()/getWritableDatаbase(), но обычно хватает того, что выше и методов выборки данных.
Далее, экземпляр этого класса создаем в нашем приложении при его запуске и выполняем запросы, то бишь проблемная часть пройдена. Почему она проблемная? Потому что, когда пользователь качает приложения с маркета, то не задумывается о вашей базе данных и может произойти что угодно. Скажем сеть пропала или процесс другой запустился, или вы написали уязвимый к ошибкам код.
Кстати, есть еще один момент, на который стоит обратить внимание. Переменную экземпляра нашего класса можно создать и хранить в объекте Application и обращаться по мере необходимости, но нужно не забывать вызывать метод close(), так как постоянный коннект к базе — это тяжелый ресурс. Кроме того могут быть коллизии при работе с базой из нескольких потоков.
Но есть и другой способ, например, создавать наш объект по мере необходимости обращения к БД. Думаю это вопрос предпочтения, но который также необходимо обсудить.
А теперь самое главное. Что, если нам понадобилось использовать уже сушествующую БД с данными в приложении?
Немного погуглив, Вы сразу наткнетесь на такую «замечательную статью» — www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications в которой, как покажется, есть нужная панацея. Но не тут то было. В ней еще и ошибок несколько.
Вот они:
1) В методе createDataBase() строка:
SQLiteDatabase dbRead = getReadableDatabase();
и далее код… содержит crash приложения на НТС Desire, потому что получаем БД для чтения(она создается), но не закрывается.
Добавляем строкой ниже dbRead.close() и фикс готов, но момент спорный.
Вот что говорит дока на тему метода getReadableDatabase():
Create and/or open a database. This will be the same object returned by getWritableDatabase() unless some problem, such as a full disk, requires the database to be opened read-only. In that case, a read-only database object will be returned. If the problem is fixed, a future call to getWritableDatabase() may succeed, in which case the read-only database object will be closed and the read/write object will be returned in the future.
Like getWritableDatabase(), this method may take a long time to return, so you should not call it from the application main thread, including from ContentProvider.onCreate().
И так. Данный метод не стоит вызывать в главном потоке приложения. В остальном все понятно.
2) Ошибка: No such table android_metadata. Автор поста выкрутился, создав данную таблицу заранее в БД. Не знаю на сколько это правильный способ, но данная таблица создается в каждой sqlite-бд системой и содержит текущую локаль.
3) Ошибка: Unable to open database file. Здесь много мнений, разных мнений, которые Вы можете прочесть по ссылкам ниже.
Возможно, что проблемы связаны с тем, что один поток блокирует БД и второй не может к ней обратиться, возможно проблема в правах доступа к приложению(было замечено, что чаще проблемы с БД проявляются на телефонах марки НТС именно на тех моделях, которые нельзя рутануть, хотя не только на них, например на планшетах Асер), но как бы то ни было проблемы эти есть.
Я склоняюсь к варианту, что проблема в потоках, не зря ведь нам не рекомендуют вызывать методы создания базы в главном потоке.
Возможно выходом из этого будет следующее решение(рассматривается вариант №2). Используя первый вариант работы с базой, наполнить ее данными после создания, например:
Данный подход еще нужно проверить на практике, но так как этот пост нацелен на выработку верного коллективного решения по данной тематике, то комментарии и пробы на даннную тему только приветствуются.
Мораль истории такова: если вы нашли какой-то хороший кусок кода для вашего решения, то проверьте его, не поленитесь, прежде чем копипастить в свой проект.
Вцелом, данный пост показывает(касательно способа №2) как делать не надо, но и также содержит пару любопытных мыслей.
Метод getReadableDatabase() можно переопределить например так:
Кстати: следуя практике самой платформы, поле первичного ключа стоит называть «_id».
Пишите в комментарии свои используемые практики. Мы сделаем данный пост лучше для всех, а может и мир станет чуточку добрее.
UPD Только что проверил свой подход. Все работает в эмуляторе, но будьте осторожны.
Файлик data.txt лежит в assets такой:
Zametka #1
Zametka #2
Zametka #3
Zametka #4
И класс приложения:
Отмечу, что данный класс используется только для демонстрации и проверки того, что произойдет при вызове методов getReadableDatabase()/getWritableDatabase() и создании базы. В реальных проектах код нужно адаптировать.
Кроме того в базе появилась табличка android_metadata(без моего участия), поэтому указанная выше ошибка решена.
Надеюсь кому-то пригодится.
Любопытные дополнения №1(от хабраюзера Kalobok)
Источник
Android SearchView in Room Database
SearchView in databases is a pretty basic functionality that you can see in most of the applications in your day-to-day life, then why not, you should learn and implement it. it is not too much complicated to implement in your application. There are a lot of easier ways that are how you can implement it. The tasks that you should use to implement for implementing searchView in-app are:-
- You need to create a menu item setting actionViewClass to SearchView and set other action view attributes
- Then inflate the menu in the onCreateOptionsMenu() method of the action where you want the search feature.
- Then get the SearchView object from the menu and add SearchView.OnQueryTextListener to it by calling setOnQueryTextListener method.
- SearchView.OnQueryTextListener has two callback methods onQueryTextSubmit and onQueryTextChange
- Method onQueryTextSubmit gets called when the user submits a search by hitting enter button or clicking submit button on the search widget.
In this method, database search can be performed using the text entered into the search view widget. You can enable the search button in the search view widget by calling the setSubmitButtonEnabled method and passing the boolean value of true. it’s a basic idea that how it works. But we are going to discuss the most efficient way for searching data from the room database, for that, you should know about some concepts like:
We are not going to create an app from scratch apart from that, we are providing the source code for initial things like
We are giving you a quick overview of the project, then you will understand it very easily. Download the project by Click Here.
Step by Step Implementation
Step 1: Download the project from GitHub and Add it to your android studio
We hope you all know that how to import existing projects to the android studio if don’t then go to file > open > select downloaded project > then wait… for finish project build
Step 2: build.Gradle files
Navigate to the app > Gradle Scripts > build.Gradle file and add the below dependencies in the dependencies section.
- We have added some dependencies and plugins
- and enable view binding
Step 3: Creating Entity/Table
Источник