persistent storage using perst lite in android

39
Persistent Storage using Perst Lite in Android

Upload: joben

Post on 16-Jan-2016

52 views

Category:

Documents


0 download

DESCRIPTION

Persistent Storage using Perst Lite in Android. Introduction. Android by default uses SQLLite to handle data storage SQLLite is a relational database style storage Requires using SQL based concepts to query for data Require mapping from raw data to object fields Not very object-oriented. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Persistent  Storage using Perst Lite  in Android

Persistent Storage using

Perst Lite in Android

Page 2: Persistent  Storage using Perst Lite  in Android

IntroductionIntroduction

Android by default uses SQLLite to handle data storage

SQLLite is a relational database style storage Requires using SQL based concepts to query for data Require mapping from raw data to object fields Not very object-oriented

Page 3: Persistent  Storage using Perst Lite  in Android

Perst LitePerst Lite

Perst Lite is an Object-Oriented Database Management System (OODBMS) with a small memory footprint meant for mobile devices

A from scratch implementation of persistence Working directly with objects not columns and tables Implements Persistence by reachability High-speed indexed lookups and Query-by-Example

Open-source and usable for free on any non-commercial project

Page 4: Persistent  Storage using Perst Lite  in Android

DependenciesDependencies

In order for the Perst classes to be available to you, you must include the PerstAndroid.jar in your Build Path and Export it

This was pre-built for use in this course Generally, you need to build it yourself

This will apply to any third party library you need included in your application

Page 5: Persistent  Storage using Perst Lite  in Android

Dependencies To set the build path

Copy the PerstAndroid.jar to the root of your project Right click the project folder Select Build Path -> Configure Build Path Select Libraries Tab Add JAR -> select your PerstAndroid.jar Select Order/Export Tab Check the PerstAndroid.jar

PerstAndroid.jar should now appear in the Referenced Libraries node of the project

Page 6: Persistent  Storage using Perst Lite  in Android

Permissions

Page 7: Persistent  Storage using Perst Lite  in Android

PermissionsPermissions

Android requires sensitive operations to be marked with permissions

File access Network access SMS access Etc

Permissions are attached to the Android Manifest

If permissions are not proper placed, APIs needing them will fail

Page 8: Persistent  Storage using Perst Lite  in Android

Example

Specific APIs will list which permissions are required by them in order to run

These can be added in the XML or via the GUI

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package=“admu.edu.cs119" android:versionCode="1" android:versionName="1.0">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.SEND_SMS"></uses-permission> <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest>

Page 9: Persistent  Storage using Perst Lite  in Android

Perst permissions

The following permissions are required in order for Perst to run

android.permission.WRITE_EXTERNAL_STORAGE

Page 10: Persistent  Storage using Perst Lite  in Android

Application Management

Page 11: Persistent  Storage using Perst Lite  in Android

Application Management

Perst will create a file in the SD card to represent its database

This file will remain in place even after the application has been shut off and use this when it starts again i.e. the data will persist between app starts

In order to “reset” the application state to its initial stat, you will need to clear application data

Page 12: Persistent  Storage using Perst Lite  in Android

Example

When viewing the application you have the option to empty out any previously stored data Hit Clear data

Page 13: Persistent  Storage using Perst Lite  in Android

PerstLite

Page 14: Persistent  Storage using Perst Lite  in Android

PerstLitePerstLite

PerstLite has several concepts that need to be understood to be able to use it Storage Root Object Persistent classes Reachability Index

Page 15: Persistent  Storage using Perst Lite  in Android

Storage

Page 16: Persistent  Storage using Perst Lite  in Android

StorageStorage

The Storage interface provides the methods for accessing the object database This abstracts how the DB is implemented

SD card, etc.

A Storage instance is created using a factory method// get instance of the storageStorage db = StorageFactory.getInstance().createStorage();

// open the database once you have storage instancedb.open(databasePath, 40*1024); // min 40k

Page 17: Persistent  Storage using Perst Lite  in Android

Defining the database path The default

Android file system is read-only

You will need to find the actual path to the db file by first opening it and then getting the absolute path to it

String databasePath = "test.dbs";try{ // MODE_APPEND is needed or else the file will auto-delete openFileOutput(databasePath, Context.MODE_APPEND).close();}catch(Exception e){ throw new RuntimeException(e);}databasePath = getFileStreamPath(databasePath).getAbsolutePath();

System.out.println("Initializing: "+databasePath);

// open the databasedb.open(databasePath, 40*1024);

Page 18: Persistent  Storage using Perst Lite  in Android

Opening the databaseOpening the database

The database file is opened using the open(String name, int pagesize) The name corresponds to the filename of the db

file (you can actually see this file in the /appdb folder)

The pagesize is how much memory to allocate to Perst The minimum size is 40*1024 bytes This is used as its internal cache

Page 19: Persistent  Storage using Perst Lite  in Android

Closing the DatabaseClosing the Database

Perst keeps data in memory as much as possible to prevent unnecessary saves to the file system which is significantly slower

However, premature termination of the app can prevent changes from being saved

In order to close the DB correctly, you must invoke close() on the Storage If the incorrectly closed, Perst will try to recover what it can on the

next startup.

Page 20: Persistent  Storage using Perst Lite  in Android

Examplepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Storage db = StorageFactory.getInstance().createStorage(); String databasePath = getAbsolutePath("test.dbs"); db.open(databasePath, 40*1024); // open the database MyRootClass root = (MyRootClass)db.getRoot(); // check if a root object is present in this file if (root == null) {

root = new MyRootClass(); // create root objectroot.setText("I am new text");db.setRoot(root);

TextView tf = (TextView) findViewById(R.id.text);tf.setText("Saving root");

} else { TextView tf = (TextView) findViewById(R.id.text); tf.setText(root.getText()); } db.close(); }

Page 21: Persistent  Storage using Perst Lite  in Android

Example getAbsolutePath()

private String getAbsolutePath(String databasePath) {try{ // MODE_APPEND is needed or else the file will auto-delete openFileOutput(databasePath, Context.MODE_APPEND).close();}catch(Exception e){ throw new RuntimeException(e);} databasePath = getFileStreamPath(databasePath).getAbsolutePath();

return databasePath;} NOTE: openFileOutput() and

getFileStreamPath() are methods of Activity

Page 22: Persistent  Storage using Perst Lite  in Android

Saving objects

Page 23: Persistent  Storage using Perst Lite  in Android

Root objectRoot object

In order to be able to save anything to the Storage you must first have a root object attached to it Which must be an IPersistent subtype

Through this reference, all other IPersistent data (if any) can be retrieved. For example: Some applications need only a single set of data to be

saved Others need several lists of data and a way to pull these

lists out by name

Page 24: Persistent  Storage using Perst Lite  in Android

Registering the Root objectRegistering the Root object

When initializing a Storage file you must first invoke getRoot() to check if a root has already been attached If the method returns null, no root is attached

You must then instantiate an IPersistent type and assign this using the setRoot(IPersistent)

Page 25: Persistent  Storage using Perst Lite  in Android

ExampleExample

MyRootClass root = (MyRootClass)db.getRoot();

// get storage root

if (root == null) {

// Root is not yet defined: storage is not initialized

root = new MyRootClass(); // create root object

db.setRoot(root); // register root object

}

Page 26: Persistent  Storage using Perst Lite  in Android

Styles of Root objectsStyles of Root objects

Simple

Not so simpleStorage

Single Persistent Object

Persistent Object

Persistent Object

Persistent Object

Storage

Contains fields or collections of Persistent objects

Could be a simple Persistent subclass with nothing but primitives and Strings

Persistent Object

Collection

fields

Page 27: Persistent  Storage using Perst Lite  in Android

Styles of Root objectsStyles of Root objects

Complex

Storage Index

Persistent Object

Persistent Object

Persistent Object

Index (see later) acts as a dynamic look-up tablefor other objects

Page 28: Persistent  Storage using Perst Lite  in Android

IPersistent/PersistentIPersistent/Persistent

The IPersistent interface contains many methods. Most of these are not directly used by the developer but are used by Perst itself

The usual way to make a class work with Perst is to make the class you are saving extend the Persistent class org.garret.perst.IPersistent and org.garret.perst.Persistent This supplies all the IPersistent methods needed by the Perst In cases where extending Persistent is not possible

You will need to open the source code of Persistent and copy them to your class manually and make your class implement the IPersistent interface

Page 29: Persistent  Storage using Perst Lite  in Android

Examplepublic class MyRootClass extends Persistent {private String text;

public String getText() {return text;}

public void setText(String text) {this.text = text;}

}

Page 30: Persistent  Storage using Perst Lite  in Android

Persistence-style

There are two ways to persist data in PerstExplictlyBy Reachability

Page 31: Persistent  Storage using Perst Lite  in Android

Explicit Persistent and StorageExplicit Persistent and Storage

When using explicit persistence, a persistent object must be associated to a Storage object so that it can be saved e.g. Via constructor

Appointment(Strorage db){

super(db)}

super constructor should pass this db to the parent

A Persistent object can then be saved by calling the object’s store() method

Page 32: Persistent  Storage using Perst Lite  in Android

ExampleExample

import org.garret.perst.*;

public class Appointment extends Persistent

{private Date time;private int length;private String location;private String subject;

Appointment(){}

Appointment(Strorage db){

super(db)}

For explicit style, you need to have 2 constructors

One blank One which takes a

Storage object

Page 33: Persistent  Storage using Perst Lite  in Android

Problem with explicit persistenceProblem with explicit persistence

The problem with explicit persistence is the fact is becomes cumbersome to save a tree of objects You need to manually store each object in the

graph front the top down

Storage

Persistent Object

Persistent Object

Persistent Object

Contains fields or collections of Persistent objects

Persistent Object

Collection

fields

Page 34: Persistent  Storage using Perst Lite  in Android

Persistence by ReachabilityPersistence by Reachability

Instead of manually calling store() on an object, you can call the Storage commit()

In order for your new object to be saved, however, a path to the root object must be present (i.e. It is reachable)

NewPersistent1 will be saved on commit() but not NewPersistent2

commit() is automatically called on a Storage close()

Root Persistent Object

Storage

Vector

New persistent1

New persistent2

addElement()

contains

Page 35: Persistent  Storage using Perst Lite  in Android

Fields and CollectionsFields and Collections

Your root object can contain IPersistent type fields or collections like Lists and HashMaps Collections can be automatically saved as long

as their contents are all IPersistent types

Fields that are not meant to be persisted should be marked with the Java keyword transient

Page 36: Persistent  Storage using Perst Lite  in Android

Editing existing Persistent objectsEditing existing Persistent objects

Once a root object is saved and retrieved in subsequent runs of your program, you can edit the root’s values Including any internal objects You can manually save individual objects using their

store() method if a Storage is already associated to it

Page 37: Persistent  Storage using Perst Lite  in Android

Editing existing Persistent objectsEditing existing Persistent objects

However, when using Storage.commit() Perst will only update objects that have their modify() method called This will flag the object for saving (dirty) Perst will not resave everything, it only saves objects

that have been marked as dirty For performance purposes (re-saving all objects is

slow)

Page 38: Persistent  Storage using Perst Lite  in Android

Design considerations

When using Persistence by reachability you are relieved of the burden of manually saving an object graph

However, you are now responsible for marking changes using modify() in the changed objects in the graph

Page 39: Persistent  Storage using Perst Lite  in Android

Design considerations

Where you place the modify() is something you need to consider you can modify() at the UI level when you press

a button You can modify() at the object level

The object itself calls its own modify() when certain fields are changed, requires placing modify() in all methods of the object causing change