SlideShare a Scribd company logo
Android: data persistence
Romain Rochegude
2016.09.30
1
Introduction
2
Introduction
• POO basics: modeling the domain
• Modeling domain objects and their interactions
• Data bound with a remote API
• Need of a local database
3
The native way
4
The “raw” way
private static final String
SQL_CREATE_ENTRIES =
"CREATE TABLE REPO (" +
"_ID INTEGER PRIMARY KEY," +
"NAME TEXT)";
private static final String
SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS REPO ";
5
• Subclass SQLiteOpenHelper
public class ReposDbHelper extends
SQLiteOpenHelper {
public static final int
DATABASE_VERSION = 1;
public static final String
DATABASE_NAME = "repos.db";
public ReposDbHelper(Context
context) {
super(context, DATABASE_NAME,
null, DATABASE_VERSION);
} 6
//...
public void onCreate(SQLiteDatabase
db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase
db, int oldVersion, int
newVersion) {
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
}
7
• Get an instance of SQLiteOpenHelper
ReposDbHelper dbHelper =
new ReposDbHelper(getContext());
8
• Put Information into a Database
SQLiteDatabase db =
dbHelper.getWritableDatabase();
ContentValues values = new
ContentValues();
values.put("name", "a sample name");
long newRowId = db.insert("REPO", null,
values);
9
• Read Information from a Database
SQLiteDatabase db =
dbHelper.getReadableDatabase();
String[] projection = { "_id", "name" };
String selection = "NAME = ?";
String[] selectionArgs = { "a sample
name" };
String sortOrder = "NAME DESC";
10
Cursor cursor = db.query(
"REPO",
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
cursor.moveToFirst();
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow("_ID")
);
11
The ContentProvider way
• Provide a ContentProvider subclass
dedicated to the application
public class RepoProvider extends
ContentProvider {
}
12
• Define a specific UriMatcher and configure
available URI
public class RepoProvider extends
ContentProvider {
private static final UriMatcher
sUriMatcher =
new
UriMatcher(UriMatcher.NO_MATCH);
}
13
static {
sUriMatcher.addURI("fr.test.app.provider",
"repo", 1);
sUriMatcher.addURI("fr.test.app.provider",
"repo/#", 2);
}
14
• Override various CRUD methods
public Cursor query(
Uri uri,
String[] projection,
String selection,
String[] selectionArgs,
String sortOrder) {
//...
15
//...
switch (sUriMatcher.match(uri)) {
case 2:
selection = selection + "_ID = "
+ uri.getLastPathSegment();
break;
default:
//...
}
16
• Use it through a ContentResolver instance
mCursor = getContentResolver().query(
"fr.test.app.provider/repo/2",
mProjection,
mSelectionClause,
mSelectionArgs,
mSortOrder);
17
• Refer to the open-sourced Google’s iosched
application
• Helpful libraries to simplify the deal with a
ContentProvider:
• ProviGen
• AutoValue: Cursor Extension
18
Async management
• Perform CRUD operations outside of the main
thread
19
Query data using Loader
• To query the ContentProvider in an
Activity, make it implementing
LoaderManager.LoaderCallbacks<Cursor>
public class ReposListActivity
extends FragmentActivity
implements
LoaderManager.LoaderCallbacks<Cursor>
{
}
20
• Start loading data with a loader identifier
getLoaderManager()
.initLoader(LOADER_REPOS, null,
this);
• Implement LoaderCallbacks. . .
21
• . . . to create the CursorLoader
@Override
public Loader<Cursor> onCreateLoader(
int id, Bundle bundle) {
if(id == LOADER_REPOS) {
return new CursorLoader(
this,
"fr.test.app.provider/repo",
mProjection,
null, null, null);
}
//...
} 22
• . . . and deal with result
@Override
public void
onLoadFinished(Loader<Cursor> loader,
Cursor cursor) {
if(loader.getId() == LOADER_REPOS){
// ...
}
}
23
• See also: AsyncQueryHandler
24
The ORM way
25
The well-known: ORMLite
• Declare your model using ORMLite annotations
@DatabaseTable(tableName = "REPO")
public class RepoEntity {
@DatabaseField(columnName = "_ID",
generatedId = true)
public long _id;
@DatabaseField
public String name;
}
26
• declare the corresponding DAO
public class DAORepo extends
BaseDaoImpl<RepoEntity, Long> {
public DAORepo(ConnectionSource cs)
throws SQLException {
this(cs, RepoEntity.class);
}
//...
}
27
• subclass OrmLiteSqliteOpenHelper
public class DatabaseHelperTest
extends OrmLiteSqliteOpenHelper {
private static final String
DATABASE_NAME = "test.db";
private static final int
DATABASE_VERSION = 1;
//...
28
//...
public DatabaseHelperTest(
Context context) {
super(context,
DATABASE_NAME,
null,
DATABASE_VERSION,
R.raw.ormlite_config);
}
//...
29
//...
@Override
public void onCreate(SQLiteDatabase db,
ConnectionSource cs) {
TableUtils.createTable(cs,
RepoEntity.class);
}
@Override
public void onUpgrade(SQLiteDatabase db,
ConnectionSource cs, int oldVersion,
int newVersion) {
//...
}
30
• get the requested DAO
DatabaseHelperTest helper = //...
ConnectionSource cs =
helper.getConnectionSource();
DatabaseTableConfig<RepoEntity>
tableConfig =
DatabaseTableConfigUtil.fromClass(cs,
RepoEntity.class);
DAORepo dao = new DAORepo(cs,
tableConfig); 31
• perform CRUD operations
// create
RepoEntity repo =
new RepoEntity("a sample name");
dao.create(repo);
32
// read
List<RepoEntity> repos =
dao.queryBuilder()
.where()
.eq("name", "a sample name")
.query();
33
• Performance: orm-gap gradle plugin
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath
'com.github.stephanenicolas.ormgap'
+ ':ormgap-plugin:1.0.0-SNAPSHOT'
}
}
apply plugin: 'ormgap' 34
• generate an ORMLite configuration file that
boosts DAOs creations
• to use this file
public RepoDatabaseHelper(Context
context) {
super(context,
DATABASE_NAME,
null,
DATABASE_VERSION,
R.raw.ormlite_config);
}
35
The attractive way: requery
• Object mapping
• SQL generator
• RxJava and Java 8 support
• No reflection, compile-time processing and
generation
• Relationships support
• Callback method (@PostLoad)
• Custom type converters
36
• Define object mapping
@Entity
abstract class Repo {
@Key @Generated
int id;
String name;
}
37
• Easy to perform SQL queries
Result<Repo> repos = data
.select(Repo.class)
.where(Repo.NAME.lower().like("%sample%"))
.orderBy(Repo.ID.desc())
.get();
38
Async management: RxJava
• Get a specific instance of SingleEntityStore
DatabaseSource dbSource =
new DatabaseSource(context,
Models.DEFAULT, "test.db", 1);
Configuration conf =
dbSource.getConfiguration();
SingleEntityStore<Persistable> data =
RxSupport.toReactiveStore(new
EntityDataStore<>(conf));
39
• and use it the RX way
data.select(RepoEntity.class)
.get()
.subscribeOn(Schedulers.newThread())
.subscribe(/*...*/)
40
Conclusion
41
Conclusion
• Personal assessments of each way
ContentProvider ORMLite requery
setup - + +
performance + - +
readability - + +
maintainability - + +
42
Ad

More Related Content

What's hot (20)

Building node.js applications with Database Jones
Building node.js applications with Database JonesBuilding node.js applications with Database Jones
Building node.js applications with Database Jones
John David Duncan
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQL
John David Duncan
 
My sql tutorial-oscon-2012
My sql tutorial-oscon-2012My sql tutorial-oscon-2012
My sql tutorial-oscon-2012
John David Duncan
 
[Android] Data Storage
[Android] Data Storage[Android] Data Storage
[Android] Data Storage
Nikmesoft Ltd
 
Learn PHP Lacture2
Learn PHP Lacture2Learn PHP Lacture2
Learn PHP Lacture2
ADARSH BHATT
 
Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile apps
Ivano Malavolta
 
Local Storage
Local StorageLocal Storage
Local Storage
Ivano Malavolta
 
SQLITE Android
SQLITE AndroidSQLITE Android
SQLITE Android
Sourabh Sahu
 
Mysql all
Mysql allMysql all
Mysql all
Prof. Wim Van Criekinge
 
Sequelize
SequelizeSequelize
Sequelize
Tarek Raihan
 
Jdbc Java Programming
Jdbc Java ProgrammingJdbc Java Programming
Jdbc Java Programming
chhaichivon
 
MySQL for beginners
MySQL for beginnersMySQL for beginners
MySQL for beginners
Saeid Zebardast
 
Hive commands
Hive commandsHive commands
Hive commands
Ganesh Sanap
 
eZ Publish cluster unleashed revisited
eZ Publish cluster unleashed revisitedeZ Publish cluster unleashed revisited
eZ Publish cluster unleashed revisited
Bertrand Dunogier
 
Brief introduction of Slick
Brief introduction of SlickBrief introduction of Slick
Brief introduction of Slick
Knoldus Inc.
 
MySql:Introduction
MySql:IntroductionMySql:Introduction
MySql:Introduction
DataminingTools Inc
 
lab56_db
lab56_dblab56_db
lab56_db
tutorialsruby
 
Softshake - Offline applications
Softshake - Offline applicationsSoftshake - Offline applications
Softshake - Offline applications
jeromevdl
 
REST Basics
REST BasicsREST Basics
REST Basics
Ivano Malavolta
 
Database Connectivity in PHP
Database Connectivity in PHPDatabase Connectivity in PHP
Database Connectivity in PHP
Taha Malampatti
 

Viewers also liked (15)

Android application architecture
Android application architectureAndroid application architecture
Android application architecture
Romain Rochegude
 
Android custom listview
Android custom listviewAndroid custom listview
Android custom listview
parmistech
 
Persistence in Android
Persistence in AndroidPersistence in Android
Persistence in Android
ma-polimi
 
Android Custom view
Android Custom view Android Custom view
Android Custom view
Theodore(Yongbin) Cha
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
Christian Melchior
 
Google android Activity lifecycle
Google android Activity lifecycle Google android Activity lifecycle
Google android Activity lifecycle
University of Potsdam
 
Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2
Vinaykumar Hebballi
 
Json vs Gson vs Jackson
Json vs Gson vs JacksonJson vs Gson vs Jackson
Json vs Gson vs Jackson
Vinaykumar Hebballi
 
Android Life Cycle
Android Life CycleAndroid Life Cycle
Android Life Cycle
mssaman
 
Android development - ListView & Adapter
Android development - ListView & AdapterAndroid development - ListView & Adapter
Android development - ListView & Adapter
Lope Emano
 
Android life cycle
Android life cycleAndroid life cycle
Android life cycle
瑋琮 林
 
Android lifecycle
Android lifecycleAndroid lifecycle
Android lifecycle
Kumar
 
Introduction to Listview in Android
Introduction to Listview in AndroidIntroduction to Listview in Android
Introduction to Listview in Android
technoguff
 
ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]
Somkiat Khitwongwattana
 
Android activity lifecycle
Android activity lifecycleAndroid activity lifecycle
Android activity lifecycle
Soham Patel
 
Android application architecture
Android application architectureAndroid application architecture
Android application architecture
Romain Rochegude
 
Android custom listview
Android custom listviewAndroid custom listview
Android custom listview
parmistech
 
Persistence in Android
Persistence in AndroidPersistence in Android
Persistence in Android
ma-polimi
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
Christian Melchior
 
Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2Open Ldap Integration and Configuration with Lifray 6.2
Open Ldap Integration and Configuration with Lifray 6.2
Vinaykumar Hebballi
 
Android Life Cycle
Android Life CycleAndroid Life Cycle
Android Life Cycle
mssaman
 
Android development - ListView & Adapter
Android development - ListView & AdapterAndroid development - ListView & Adapter
Android development - ListView & Adapter
Lope Emano
 
Android life cycle
Android life cycleAndroid life cycle
Android life cycle
瑋琮 林
 
Android lifecycle
Android lifecycleAndroid lifecycle
Android lifecycle
Kumar
 
Introduction to Listview in Android
Introduction to Listview in AndroidIntroduction to Listview in Android
Introduction to Listview in Android
technoguff
 
ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]ListView and Custom ListView on Android Development [Thai]
ListView and Custom ListView on Android Development [Thai]
Somkiat Khitwongwattana
 
Android activity lifecycle
Android activity lifecycleAndroid activity lifecycle
Android activity lifecycle
Soham Patel
 
Ad

Similar to Android Data Persistence (20)

Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem novaKotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Víctor Leonel Orozco López
 
Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
 
Data Management 3: Bulletproof Data Management
Data Management 3: Bulletproof Data ManagementData Management 3: Bulletproof Data Management
Data Management 3: Bulletproof Data Management
MongoDB
 
Cloud nativeworkshop
Cloud nativeworkshopCloud nativeworkshop
Cloud nativeworkshop
Emily Jiang
 
Back to the future with Java 7 (Geekout June/2011)
Back to the future with Java 7 (Geekout June/2011)Back to the future with Java 7 (Geekout June/2011)
Back to the future with Java 7 (Geekout June/2011)
Martijn Verburg
 
Real world cross-platform testing
Real world cross-platform testingReal world cross-platform testing
Real world cross-platform testing
Peter Edwards
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
Shem Magnezi
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
Jorge Lopez-Malla
 
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
TAISEEREISA
 
Tools and Tips for Moodle Developers - #mootus16
 Tools and Tips for Moodle Developers - #mootus16 Tools and Tips for Moodle Developers - #mootus16
Tools and Tips for Moodle Developers - #mootus16
Dan Poltawski
 
Jdbc
JdbcJdbc
Jdbc
Jussi Pohjolainen
 
Java JDBC
Java JDBCJava JDBC
Java JDBC
Jussi Pohjolainen
 
Laravel for Web Artisans
Laravel for Web ArtisansLaravel for Web Artisans
Laravel for Web Artisans
Raf Kewl
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
Christian Panadero
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
Jiayun Zhou
 
Phinx talk
Phinx talkPhinx talk
Phinx talk
Michael Peacock
 
Save data in to sqlite
Save data in to sqliteSave data in to sqlite
Save data in to sqlite
Junifar hidayat
 
Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
Paulo Victor Gomes
 
MYSQL - PHP Database Connectivity
MYSQL - PHP Database ConnectivityMYSQL - PHP Database Connectivity
MYSQL - PHP Database Connectivity
V.V.Vanniaperumal College for Women
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
Shawn Brito
 
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem novaKotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Kotlin+MicroProfile: Ensinando 20 anos para uma linguagem nova
Víctor Leonel Orozco López
 
Data Management 3: Bulletproof Data Management
Data Management 3: Bulletproof Data ManagementData Management 3: Bulletproof Data Management
Data Management 3: Bulletproof Data Management
MongoDB
 
Cloud nativeworkshop
Cloud nativeworkshopCloud nativeworkshop
Cloud nativeworkshop
Emily Jiang
 
Back to the future with Java 7 (Geekout June/2011)
Back to the future with Java 7 (Geekout June/2011)Back to the future with Java 7 (Geekout June/2011)
Back to the future with Java 7 (Geekout June/2011)
Martijn Verburg
 
Real world cross-platform testing
Real world cross-platform testingReal world cross-platform testing
Real world cross-platform testing
Peter Edwards
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
Shem Magnezi
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
Jorge Lopez-Malla
 
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
Chapter 3.pptx Oracle SQL or local Android database setup SQL, SQL-Lite, codi...
TAISEEREISA
 
Tools and Tips for Moodle Developers - #mootus16
 Tools and Tips for Moodle Developers - #mootus16 Tools and Tips for Moodle Developers - #mootus16
Tools and Tips for Moodle Developers - #mootus16
Dan Poltawski
 
Laravel for Web Artisans
Laravel for Web ArtisansLaravel for Web Artisans
Laravel for Web Artisans
Raf Kewl
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
Christian Panadero
 
Java EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSFJava EE 6 CDI Integrates with Spring & JSF
Java EE 6 CDI Integrates with Spring & JSF
Jiayun Zhou
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
Shawn Brito
 
Ad

More from Romain Rochegude (6)

Reuse features in Android applications
Reuse features in Android applicationsReuse features in Android applications
Reuse features in Android applications
Romain Rochegude
 
Write an Android library
Write an Android libraryWrite an Android library
Write an Android library
Romain Rochegude
 
Android utilities
Android utilitiesAndroid utilities
Android utilities
Romain Rochegude
 
Java objects on steroids
Java objects on steroidsJava objects on steroids
Java objects on steroids
Romain Rochegude
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architecture
Romain Rochegude
 
Android: a full-stack to consume a REST API
Android: a full-stack to consume a REST APIAndroid: a full-stack to consume a REST API
Android: a full-stack to consume a REST API
Romain Rochegude
 
Reuse features in Android applications
Reuse features in Android applicationsReuse features in Android applications
Reuse features in Android applications
Romain Rochegude
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architecture
Romain Rochegude
 
Android: a full-stack to consume a REST API
Android: a full-stack to consume a REST APIAndroid: a full-stack to consume a REST API
Android: a full-stack to consume a REST API
Romain Rochegude
 

Recently uploaded (20)

Time Estimation: Expert Tips & Proven Project Techniques
Time Estimation: Expert Tips & Proven Project TechniquesTime Estimation: Expert Tips & Proven Project Techniques
Time Estimation: Expert Tips & Proven Project Techniques
Livetecs LLC
 
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint PresentationFrom Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
Shay Ginsbourg
 
Passive House Canada Conference 2025 Presentation [Final]_v4.ppt
Passive House Canada Conference 2025 Presentation [Final]_v4.pptPassive House Canada Conference 2025 Presentation [Final]_v4.ppt
Passive House Canada Conference 2025 Presentation [Final]_v4.ppt
IES VE
 
How to Install and Activate ListGrabber Plugin
How to Install and Activate ListGrabber PluginHow to Install and Activate ListGrabber Plugin
How to Install and Activate ListGrabber Plugin
eGrabber
 
How to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryErrorHow to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryError
Tier1 app
 
Troubleshooting JVM Outages – 3 Fortune 500 case studies
Troubleshooting JVM Outages – 3 Fortune 500 case studiesTroubleshooting JVM Outages – 3 Fortune 500 case studies
Troubleshooting JVM Outages – 3 Fortune 500 case studies
Tier1 app
 
Robotic Process Automation (RPA) Software Development Services.pptx
Robotic Process Automation (RPA) Software Development Services.pptxRobotic Process Automation (RPA) Software Development Services.pptx
Robotic Process Automation (RPA) Software Development Services.pptx
julia smits
 
How I solved production issues with OpenTelemetry
How I solved production issues with OpenTelemetryHow I solved production issues with OpenTelemetry
How I solved production issues with OpenTelemetry
Cees Bos
 
NYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdfNYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdf
AUGNYC
 
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb ClarkDeploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Peter Caitens
 
Autodesk Inventor Crack (2025) Latest
Autodesk Inventor    Crack (2025) LatestAutodesk Inventor    Crack (2025) Latest
Autodesk Inventor Crack (2025) Latest
Google
 
Download 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-ActivatedDownload 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-Activated
Web Designer
 
Sequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptxSequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptx
aashrithakondapalli8
 
What Do Candidates Really Think About AI-Powered Recruitment Tools?
What Do Candidates Really Think About AI-Powered Recruitment Tools?What Do Candidates Really Think About AI-Powered Recruitment Tools?
What Do Candidates Really Think About AI-Powered Recruitment Tools?
HireME
 
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-RuntimeReinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Natan Silnitsky
 
sequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineeringsequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineering
aashrithakondapalli8
 
Top 12 Most Useful AngularJS Development Tools to Use in 2025
Top 12 Most Useful AngularJS Development Tools to Use in 2025Top 12 Most Useful AngularJS Development Tools to Use in 2025
Top 12 Most Useful AngularJS Development Tools to Use in 2025
GrapesTech Solutions
 
Do not let staffing shortages and limited fiscal view hamper your cause
Do not let staffing shortages and limited fiscal view hamper your causeDo not let staffing shortages and limited fiscal view hamper your cause
Do not let staffing shortages and limited fiscal view hamper your cause
Fexle Services Pvt. Ltd.
 
GC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance EngineeringGC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance Engineering
Tier1 app
 
Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...
Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...
Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...
OnePlan Solutions
 
Time Estimation: Expert Tips & Proven Project Techniques
Time Estimation: Expert Tips & Proven Project TechniquesTime Estimation: Expert Tips & Proven Project Techniques
Time Estimation: Expert Tips & Proven Project Techniques
Livetecs LLC
 
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint PresentationFrom Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
From Vibe Coding to Vibe Testing - Complete PowerPoint Presentation
Shay Ginsbourg
 
Passive House Canada Conference 2025 Presentation [Final]_v4.ppt
Passive House Canada Conference 2025 Presentation [Final]_v4.pptPassive House Canada Conference 2025 Presentation [Final]_v4.ppt
Passive House Canada Conference 2025 Presentation [Final]_v4.ppt
IES VE
 
How to Install and Activate ListGrabber Plugin
How to Install and Activate ListGrabber PluginHow to Install and Activate ListGrabber Plugin
How to Install and Activate ListGrabber Plugin
eGrabber
 
How to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryErrorHow to Troubleshoot 9 Types of OutOfMemoryError
How to Troubleshoot 9 Types of OutOfMemoryError
Tier1 app
 
Troubleshooting JVM Outages – 3 Fortune 500 case studies
Troubleshooting JVM Outages – 3 Fortune 500 case studiesTroubleshooting JVM Outages – 3 Fortune 500 case studies
Troubleshooting JVM Outages – 3 Fortune 500 case studies
Tier1 app
 
Robotic Process Automation (RPA) Software Development Services.pptx
Robotic Process Automation (RPA) Software Development Services.pptxRobotic Process Automation (RPA) Software Development Services.pptx
Robotic Process Automation (RPA) Software Development Services.pptx
julia smits
 
How I solved production issues with OpenTelemetry
How I solved production issues with OpenTelemetryHow I solved production issues with OpenTelemetry
How I solved production issues with OpenTelemetry
Cees Bos
 
NYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdfNYC ACE 08-May-2025-Combined Presentation.pdf
NYC ACE 08-May-2025-Combined Presentation.pdf
AUGNYC
 
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb ClarkDeploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Deploying & Testing Agentforce - End-to-end with Copado - Ewenb Clark
Peter Caitens
 
Autodesk Inventor Crack (2025) Latest
Autodesk Inventor    Crack (2025) LatestAutodesk Inventor    Crack (2025) Latest
Autodesk Inventor Crack (2025) Latest
Google
 
Download 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-ActivatedDownload 4k Video Downloader Crack Pre-Activated
Download 4k Video Downloader Crack Pre-Activated
Web Designer
 
Sequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptxSequence Diagrams With Pictures (1).pptx
Sequence Diagrams With Pictures (1).pptx
aashrithakondapalli8
 
What Do Candidates Really Think About AI-Powered Recruitment Tools?
What Do Candidates Really Think About AI-Powered Recruitment Tools?What Do Candidates Really Think About AI-Powered Recruitment Tools?
What Do Candidates Really Think About AI-Powered Recruitment Tools?
HireME
 
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-RuntimeReinventing Microservices Efficiency and Innovation with Single-Runtime
Reinventing Microservices Efficiency and Innovation with Single-Runtime
Natan Silnitsky
 
sequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineeringsequencediagrams.pptx software Engineering
sequencediagrams.pptx software Engineering
aashrithakondapalli8
 
Top 12 Most Useful AngularJS Development Tools to Use in 2025
Top 12 Most Useful AngularJS Development Tools to Use in 2025Top 12 Most Useful AngularJS Development Tools to Use in 2025
Top 12 Most Useful AngularJS Development Tools to Use in 2025
GrapesTech Solutions
 
Do not let staffing shortages and limited fiscal view hamper your cause
Do not let staffing shortages and limited fiscal view hamper your causeDo not let staffing shortages and limited fiscal view hamper your cause
Do not let staffing shortages and limited fiscal view hamper your cause
Fexle Services Pvt. Ltd.
 
GC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance EngineeringGC Tuning: A Masterpiece in Performance Engineering
GC Tuning: A Masterpiece in Performance Engineering
Tier1 app
 
Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...
Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...
Surviving a Downturn Making Smarter Portfolio Decisions with OnePlan - Webina...
OnePlan Solutions
 

Android Data Persistence

  • 1. Android: data persistence Romain Rochegude 2016.09.30 1
  • 3. Introduction • POO basics: modeling the domain • Modeling domain objects and their interactions • Data bound with a remote API • Need of a local database 3
  • 5. The “raw” way private static final String SQL_CREATE_ENTRIES = "CREATE TABLE REPO (" + "_ID INTEGER PRIMARY KEY," + "NAME TEXT)"; private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS REPO "; 5
  • 6. • Subclass SQLiteOpenHelper public class ReposDbHelper extends SQLiteOpenHelper { public static final int DATABASE_VERSION = 1; public static final String DATABASE_NAME = "repos.db"; public ReposDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } 6
  • 7. //... public void onCreate(SQLiteDatabase db) { db.execSQL(SQL_CREATE_ENTRIES); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(SQL_DELETE_ENTRIES); onCreate(db); } } 7
  • 8. • Get an instance of SQLiteOpenHelper ReposDbHelper dbHelper = new ReposDbHelper(getContext()); 8
  • 9. • Put Information into a Database SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("name", "a sample name"); long newRowId = db.insert("REPO", null, values); 9
  • 10. • Read Information from a Database SQLiteDatabase db = dbHelper.getReadableDatabase(); String[] projection = { "_id", "name" }; String selection = "NAME = ?"; String[] selectionArgs = { "a sample name" }; String sortOrder = "NAME DESC"; 10
  • 11. Cursor cursor = db.query( "REPO", projection, selection, selectionArgs, null, null, sortOrder); cursor.moveToFirst(); long itemId = cursor.getLong( cursor.getColumnIndexOrThrow("_ID") ); 11
  • 12. The ContentProvider way • Provide a ContentProvider subclass dedicated to the application public class RepoProvider extends ContentProvider { } 12
  • 13. • Define a specific UriMatcher and configure available URI public class RepoProvider extends ContentProvider { private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); } 13
  • 15. • Override various CRUD methods public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //... 15
  • 16. //... switch (sUriMatcher.match(uri)) { case 2: selection = selection + "_ID = " + uri.getLastPathSegment(); break; default: //... } 16
  • 17. • Use it through a ContentResolver instance mCursor = getContentResolver().query( "fr.test.app.provider/repo/2", mProjection, mSelectionClause, mSelectionArgs, mSortOrder); 17
  • 18. • Refer to the open-sourced Google’s iosched application • Helpful libraries to simplify the deal with a ContentProvider: • ProviGen • AutoValue: Cursor Extension 18
  • 19. Async management • Perform CRUD operations outside of the main thread 19
  • 20. Query data using Loader • To query the ContentProvider in an Activity, make it implementing LoaderManager.LoaderCallbacks<Cursor> public class ReposListActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> { } 20
  • 21. • Start loading data with a loader identifier getLoaderManager() .initLoader(LOADER_REPOS, null, this); • Implement LoaderCallbacks. . . 21
  • 22. • . . . to create the CursorLoader @Override public Loader<Cursor> onCreateLoader( int id, Bundle bundle) { if(id == LOADER_REPOS) { return new CursorLoader( this, "fr.test.app.provider/repo", mProjection, null, null, null); } //... } 22
  • 23. • . . . and deal with result @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { if(loader.getId() == LOADER_REPOS){ // ... } } 23
  • 24. • See also: AsyncQueryHandler 24
  • 26. The well-known: ORMLite • Declare your model using ORMLite annotations @DatabaseTable(tableName = "REPO") public class RepoEntity { @DatabaseField(columnName = "_ID", generatedId = true) public long _id; @DatabaseField public String name; } 26
  • 27. • declare the corresponding DAO public class DAORepo extends BaseDaoImpl<RepoEntity, Long> { public DAORepo(ConnectionSource cs) throws SQLException { this(cs, RepoEntity.class); } //... } 27
  • 28. • subclass OrmLiteSqliteOpenHelper public class DatabaseHelperTest extends OrmLiteSqliteOpenHelper { private static final String DATABASE_NAME = "test.db"; private static final int DATABASE_VERSION = 1; //... 28
  • 29. //... public DatabaseHelperTest( Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config); } //... 29
  • 30. //... @Override public void onCreate(SQLiteDatabase db, ConnectionSource cs) { TableUtils.createTable(cs, RepoEntity.class); } @Override public void onUpgrade(SQLiteDatabase db, ConnectionSource cs, int oldVersion, int newVersion) { //... } 30
  • 31. • get the requested DAO DatabaseHelperTest helper = //... ConnectionSource cs = helper.getConnectionSource(); DatabaseTableConfig<RepoEntity> tableConfig = DatabaseTableConfigUtil.fromClass(cs, RepoEntity.class); DAORepo dao = new DAORepo(cs, tableConfig); 31
  • 32. • perform CRUD operations // create RepoEntity repo = new RepoEntity("a sample name"); dao.create(repo); 32
  • 33. // read List<RepoEntity> repos = dao.queryBuilder() .where() .eq("name", "a sample name") .query(); 33
  • 34. • Performance: orm-gap gradle plugin buildscript { repositories { mavenCentral() } dependencies { classpath 'com.github.stephanenicolas.ormgap' + ':ormgap-plugin:1.0.0-SNAPSHOT' } } apply plugin: 'ormgap' 34
  • 35. • generate an ORMLite configuration file that boosts DAOs creations • to use this file public RepoDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config); } 35
  • 36. The attractive way: requery • Object mapping • SQL generator • RxJava and Java 8 support • No reflection, compile-time processing and generation • Relationships support • Callback method (@PostLoad) • Custom type converters 36
  • 37. • Define object mapping @Entity abstract class Repo { @Key @Generated int id; String name; } 37
  • 38. • Easy to perform SQL queries Result<Repo> repos = data .select(Repo.class) .where(Repo.NAME.lower().like("%sample%")) .orderBy(Repo.ID.desc()) .get(); 38
  • 39. Async management: RxJava • Get a specific instance of SingleEntityStore DatabaseSource dbSource = new DatabaseSource(context, Models.DEFAULT, "test.db", 1); Configuration conf = dbSource.getConfiguration(); SingleEntityStore<Persistable> data = RxSupport.toReactiveStore(new EntityDataStore<>(conf)); 39
  • 40. • and use it the RX way data.select(RepoEntity.class) .get() .subscribeOn(Schedulers.newThread()) .subscribe(/*...*/) 40
  • 42. Conclusion • Personal assessments of each way ContentProvider ORMLite requery setup - + + performance + - + readability - + + maintainability - + + 42
  翻译: