Dicoding Developer Coaching merupakan webinar, yang membahas tuntas kendala maupun pertanyaan yang sering ditanyakan di Academy Dicoding.
Tema kali ini adalah "Menyimpan Database Secara Local di Aplikasi Androidmu."
Di sini Anda akan mempelajari tentang pengembangan aplikasi pada berbagai platform yang tidak luput dari proses penyimpanan dan manipulasi data. Pada perangkat Android, terdapat beragam mekanisme penyimpanan yang bergantung pada kebutuhan aplikasi. Pada umumnya penyimpanan dan pengolahan data di Android terbagi menjadi beberapa komponen seperti penyimpan di onSavedInstanceState, penggunaan SharedPreferences, SQLite Database, Content Provider, dan lain sebagainya.
2. A database is an organized collection of structured information, or data,
typically stored electronically in a computer system.
Data within the most common types of databases in operation today is
typically modeled in rows and columns in a series of tables to make
processing and data querying efficient.
https://www.oracle.com/database/what-is-database/
5. Data Storage in Android
Storage Type Type of Data Saved Length of Time Saved
onSavedInstanceState Key-value Only when the application is opened
SharedPreferences Key-value Until the application is uninstalled / clear data
SQLite Database Local database Until the application is uninstalled / clear data
Internal/External
Storage
Multimedia or files Until the application is uninstalled / clear data
Network/Server Online database As long as the server is active
6. ● Store data with primitive data types such as
boolean, int, long, or strings that are not related
to each other.
● The concept used in this type is a key-value pair.
● Usually used to save settings/configurations and
session.
Shared Preferences
7. var sharedPref: = getSharedPreferences(
"my_pref", Context.MODE_PRIVATE)
● Create Shared Preference
val editor: SharedPreferences.Editor = sharedPref.edit()
editor.putString(NAME, "Arif")
editor.putInt(AGE, 22)
editor.apply() // OR : editor.commit()
● Save Data
var name = sharedPref.getString(NAME, "")
var name = sharedPref.getString(AGE, 0)
● Get Data
Shared Preference Example
8. ● Settings allow users to change the functionality and behavior of
an application. Such as changing theme, language, etc.
● The recommended way to integrate user configurable settings
into your application is to use the AndroidX Preference Library.
● This library manages the user interface and interacts with
storage so that you define only the individual settings that user
can configure.
● The library comes with a Material theme that provides a
consistent user experience across devices and OS versions.
Setting Preferences Example
10. Inflate Preference Screen
class MyPreferenceFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(bundle: Bundle?, s: String?) {
addPreferencesFromResource(R.xml.preferences)
...
}
}
supportFragmentManager
.beginTransaction()
.add(R.id.setting_holder, MyPreferenceFragment())
.commit()
● Create Fragment Extend to PreferenceFragmentCompat
● Add Fragment in Activity
11. Preference Screen & Shared Preference
<EditTextPreference
android:key="phone"
android:title="@string/phone_number" />
val pref = preferenceManager.sharedPreferences
phonePreference.summary = pref.getString("phone", DEFAULT_VALUE)
● Preference Key
● Read Data from SharedPreference
val phonePreference: EditTextPreference> = findPreference("phone")
● Initiate Preference Component
12. Listen for Changes to Preference Values
class MyPreferenceFragment : PreferenceFragmentCompat(),
SharedPreferences.OnSharedPreferenceChangeListener {
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
if (key == PHONE) {
phonePreference.summary = sharedPreferences.getString(PHONE, DEFAULT_VALUE)
}
}
override fun onResume() {
super.onResume()
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}
override fun onPause() {
super.onPause()
preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
}
}
13. ● SQLite is an open source database that supports standard
relationship operations commonly found in database engines
such as SQL syntax and transaction operations.
● Even though it runs like a database, sqlite is generally small in
size and can run on devices with limited memory such as
smartphones.
● SQLite is included by default on all Android devices and most
importantly no authentication process or administrative setup
is required as is done in large-scale database software.
SQLite
14. ● User Experience (Not waiting loading with Blank Screen)
● Battery life
● Saving quota
● Reduce server load and network bandwidth
● Run without internet connection area
Why We Need Local Database?
15. Table Example
id title author genre pages
1 Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin Programming 434
2 A Brief History of Time Stephen Hawking Science 212
3 Rich Dad, Poor Dad Robert T. Kiyosaki Business 195
4 The 7 Habits of Highly Effective People Stephen Covey Self-help 372
5 The Rainbow Troops Andrea Hirata Novel 304
16. class BookContract {
class BookEntry : BaseColumns {
companion object {
val TABLE_NAME = "book"
val COLUMN_TITLE = "title"
val COLUMN_AUTHOR = "author"
val COLUMN_GENRE = "genre"
val COLUMN_PAGES = "pages"
}
}
}
id title author genre pages
Database Contract
17. SQLiteOpenHelper
class BooksHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null,
DATABASE_VERSION) {
companion object {
val DATABASE_VERSION = 1
val DATABASE_NAME = "Book.db"
}
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(SQL_CREATE_ENTRIES)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL(SQL_DELETE_ENTRIES)
onCreate(db)
}
}
18. Basic Database
private val SQL_CREATE_ENTRIES="CREATE TABLE ${BookEntry.TABLE_NAME}"+
" (${BookEntry._ID} INTEGER PRIMARY KEY," +
" ${BookEntry.COLUMN_TITLE} TEXT," +
" ${BookEntry.COLUMN_AUTHOR} TEXT," +
" ${BookEntry.COLUMN_GENRE} TEXT," +
" ${BookEntry.COLUMN_PAGES} INT)"
● Create Database: "CREATE TABLE book (id INTEGER PRIMARY KEY, title
TEXT, author TEXT, genre TEXT, pages INT)"
private val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS
$BookEntry.TABLE_NAME"
● Delete Database: "DROP TABLE IF EXISTS book"
19. Insert Database
// Gets the data repository in write mode
val dbHelper: BooksHelper = BooksHelper(this)
val db: SQLiteDatabase = dbHelper.getWritableDatabase()
// Create a new map of values, where column names are the keys
val values = ContentValues()
values.put(BookEntry.COLUMN_TITLE, "Clean Code")
values.put(BookEntry.COLUMN_AUTHOR, "Robert C. Martin")
values.put(BookEntry.COLUMN_GENRE, "Programming")
values.put(BookEntry.COLUMN_PAGES, 434)
// Insert the new row, returning the primary key value of the new row
val newRowId: Long = db.insert(BookEntry.TABLE_NAME, null, values)
21. Convert Cursor to List
val bookList = ArrayList<Book>()
cursor?.apply {
while (moveToNext()) {
val id = getInt(getColumnIndexOrThrow(BookEntry._ID))
val title = getString(getColumnIndexOrThrow(BookEntry.COLUMN_TITLE))
...
bookList.add(Book(id, title, author, genre))
}
}
22.
23. Update Database
val db = dbHelper.getWritableDatabase()
val values = ContentValues()
values.put(BookEntry.COLUMN_TITLE, "Clean Architecture") // new value
val selection = BookEntry.COLUMN_GENRE + " = ?"
val selectionArgs = { "Programming" }
int count = db.update(
BookColums.TABLE_NAME,
values,
selection,
selectionArgs
)
24. Delete Database
// Define 'where' part of query.
val selection = BookColums.COLUMN_AUTHOR + " LIKE ?"
// Specify arguments in placeholder order.
val selectionArgs = { "Hirata" }
// Execute SQL statement
db.delete(
BookColums.TABLE_NAME,
selection,
selectionArgs
)
25. Raw Query
db.rawQuery("SELECT * FROM book WHERE genre = programming ORDER BY pages
DESC LIMIT 3", null)
● SELECT columns—select the columns to return, use * to return all columns
● FROM table—specify the table from which to get results
● WHERE—keyword for conditions that have to be met
● column="value"—the condition that has to be met. operators: =, LIKE, <, >
● ORDER BY—omit for default order, or ASC for ascending, DESC for
descending
● LIMIT—get a limited number of results