[main]: Add mdp to lecture notes
This commit is contained in:
70 files changed
+2759
No files matched your search
@@ -0,0 +1,240 @@
|
||||
# Storage
|
||||
|
||||
### Storage Principles
|
||||
|
||||
#### App-Specific Requirements
|
||||
|
||||
- Store files that are meant for our use only
|
||||
- Store files that we intend to share with other apps
|
||||
- e.g. taking a photo
|
||||
- Store private, primitive data
|
||||
- Config data, passwords, cookies & keys, etc.
|
||||
- Store private, structured data
|
||||
- text messages
|
||||
|
||||
#### Mobile Storage Principles
|
||||
|
||||
- Efficiency and sharing vs privacy and security
|
||||
- Limited storage capacity
|
||||
- Highly personal information stored
|
||||
- Lots of different data types stored on phone
|
||||
- Media
|
||||
- Images, videos, music
|
||||
|
||||
> Access to the mail should be protected since this is sensitive user data. However, if a reference to an image attachment is given to an image viewer, that image viewer will not have permission to open the attachment since it has no reason to hold a permission to access all e-mail.
|
||||
|
||||
##### Storage Directories
|
||||
|
||||
`/system` -> stores Android OS & libraries
|
||||
|
||||
`/data` -> where user data is stored (every application is a user)
|
||||
|
||||
`/mnt/sdcard` (symlinked as `sdcard`) -> *External* Storage
|
||||
|
||||
### Basic Logical Data Storage on Android
|
||||
|
||||
##### Different Volumes
|
||||
|
||||
###### Internal
|
||||
|
||||
- Limited space for app-specific data
|
||||
- Reliable (not *removable*)
|
||||
- Soldered RAM
|
||||
|
||||
###### External
|
||||
|
||||
- Lots of data
|
||||
- May (or may not) be physically removable
|
||||
|
||||
##### Different kinds of data
|
||||
|
||||
- Data that is only meaningful for our app should use app-specific storage
|
||||
- Shareable media content should use shared storage so that other apps can access the content
|
||||
- Also called scoped storage
|
||||
|
||||
##### File-based abstractions
|
||||
|
||||
- Shared preferences
|
||||
- File-based storage
|
||||
- SQLite database
|
||||
- Structured data, small binary blobs
|
||||
|
||||

|
||||
|
||||
## Internal File Storage
|
||||
|
||||
Internal data storage is private to the app
|
||||
|
||||
- Other apps (and the user) cannot access it
|
||||
- Kernel-enforced user perms
|
||||
- Removed on uninstall
|
||||
- Data is stored in files
|
||||
- `/data/data/com.example.project/files/`
|
||||
- Full path not accessible; `files/` becomes the chroot
|
||||
- This ensures we cannot traverse the directory upwards and gain access to other applications' files
|
||||
|
||||
##### Cache Files
|
||||
|
||||
`/data/data/com.example.project/cache`
|
||||
|
||||
`getCacheDir()` -> gets application’s file directory
|
||||
|
||||
Programmer should manage the files
|
||||
|
||||
- **May** be deleted when internal storage becomes full
|
||||
- **Will** be deleted when application is uninstalled
|
||||
- A *well-behaved* application will delete them when no longer in use
|
||||
- Recommended to use less than 1MB
|
||||
|
||||
#### Shared Preferences
|
||||
|
||||
- Stored on a per-application basis
|
||||
- e.g. saving config info (settings)
|
||||
- Should not be used for data transfer (use intents and binders instead)
|
||||
- Primitive data in key-value pairs
|
||||
- Can have multiple preference files per application
|
||||
|
||||
```xml
|
||||
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
|
||||
<map>
|
||||
<string name="colourscheme">light</string>
|
||||
</map>
|
||||
```
|
||||
|
||||
```java
|
||||
SharedPreferences settings = getSharedPreferences(CONFIG_STORAGE_NAME, 0);
|
||||
SharedPreferences.Editor editor = settings.editor;
|
||||
|
||||
if (settings.getBoolean(MainActivity.CONFIG_THEME, false))
|
||||
setTheme(...);
|
||||
else
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### External Storage
|
||||
|
||||
*Legacy name*
|
||||
|
||||
- Every Android device provides externally accessible storage (SD card)
|
||||
- Even phones without a physical SD card must have a **logical representation** of external storage
|
||||
- Most phones will have one storage device partitioned into `internal / external`
|
||||
- Phones must do this to conform to the Android API
|
||||
- *Private* Application files
|
||||
- *Internal* storage on the external partition
|
||||
- `getExternalFilesDir()`
|
||||
- `/sdcard/Android/data/com.example.project/`
|
||||
- *Public* general files
|
||||
- World reachable
|
||||
- Other apps can read and modify these files
|
||||
- Each *user* has their own *virtual* SD card
|
||||
- Can be mounted externally (and unmounted/disconnected)
|
||||
|
||||
##### Getting Access to External Storage
|
||||
|
||||
- Should check state with `Enviroment.getExternalStorageState()`
|
||||
- It is a separate file system, potentially removable
|
||||
- `Environment.MEDIA_MOUNTED`
|
||||
- `Environment.MEDIA_MOUNTED_READ_ONLY`
|
||||
- Use `getExternalStoragePublicDirectory (String type)` to obtain file for the directory
|
||||
- Media is stored by type
|
||||
- Music in the music dir, etc.
|
||||
- Pass a type to obtain the subdirectory for that type
|
||||
|
||||
##### Getting Scoped storage access
|
||||
|
||||
- To access files that other apps have created
|
||||
- We must have `READ_EXTERNAL_STORAGE` permission (in the manifest)
|
||||
- With this one permission, the app can do whatever (look at downloads, listen to music, look at pictures, etc.)
|
||||
- This is where scoped storage comes into play
|
||||
- The files must reside in the media collection (images/music/videos, etc.)
|
||||
- or request legacy storage `MANAGE_EXTERNAL_STORAGE` (before Android 11)
|
||||
- Apps only have access to
|
||||
- App-specific directory on external storage
|
||||
- Specific types of media that the app has created and contributed to well-defined collections
|
||||
- If the app takes a picture, it is allowed to store and look at that picture but not allowed to access pictures not taken by that app
|
||||
- You don't need to request perms to read/write images that we are writing to the MediaStorage
|
||||
|
||||
# Android Databases
|
||||
|
||||
When the data stored is logically structured, queries are needed to find it based on the structure.
|
||||
|
||||
- Android provides local database support
|
||||
- Can run full SQL queries
|
||||
- Each app’s databases are local to it
|
||||
- `Database.db` stored in internal storage
|
||||
- Powered by SQLite
|
||||
|
||||
#### Android and SQLite
|
||||
|
||||
- Wrapped in two main classes
|
||||
- Database represented by `SQLiteDatabase` object
|
||||
- Allows us to run SQL queries on the database
|
||||
- `SQLiteOpenHelper`
|
||||
- Supports the application lifecycle
|
||||
- `SQLiteOpenHelper` -> `onCreate()`
|
||||
- Creates the database the **first time** it is called
|
||||
- This database will exist until the application is installed
|
||||
- `SQLiteOpenHelper` -> `onUpdate(int oldVer, int newVer)`
|
||||
- Changing the version number allows the database to be dropped and recreated
|
||||
- Create an instance of our `SQLiteOpenHelper` subclass
|
||||
- Get reference to `SQLiteDatabase` using
|
||||
- `getReadableDatabase()`
|
||||
- `getWriteableDatabase()`
|
||||
|
||||
##### Querying a Database
|
||||
|
||||
`void execSQL()` -> used to execute SQL queries that don't return anything
|
||||
|
||||
`query()` and `rawQuery()`
|
||||
|
||||
- These return a Cursor object pointing to the results
|
||||
|
||||
`Cursor rawQuery (String sql, String[] selectionArgs)`
|
||||
|
||||
###### Cursors
|
||||
|
||||
- Provide random access to results of a query
|
||||
- Enable us to enumerate the rows returned by the query
|
||||
- `moveToFirst()`, `moveToNext()`
|
||||
- `getString(colIndex)`, `getInt(colIndex)`
|
||||
- Have a `close()` method to close the query when finished
|
||||
|
||||
We can pass cursors to other applications
|
||||
|
||||
###### CursorLoader
|
||||
|
||||
- A query may last some time
|
||||
- Database may be large
|
||||
- May be in a different process
|
||||
- Don’t block the main thread
|
||||
- `CursorLoader`
|
||||
- Populates views asynchronously
|
||||
- Auto-updating
|
||||
|
||||
(deprecated)
|
||||
|
||||
#### Data-Driven Views
|
||||
|
||||
- *Connect* a cursor to a `CursorAdapter` and a `ListView`
|
||||
- Think mapping rows of a database to which entry in the list
|
||||
- Each row must have an ID field
|
||||
- `RecyclerView`
|
||||
- An optimised, flexible version of the above
|
||||
- Only creates views for visible data
|
||||
- As the user scrolls, more data is added
|
||||
- We can define our own adaptor
|
||||
|
||||
### Database Abstraction
|
||||
|
||||
Abstraction of database architecture
|
||||
|
||||
- Easier to update storage code
|
||||
- Expose column indices as static class variables
|
||||
- `c.getInt(0)` ✗
|
||||
- `c.getInt(DBHelper.NAME)` ✓
|
||||
- Helper methods keep database internals from *leaking* into other classes
|
||||
- Return a collection of results rather than the cursor
|
||||
- **Sanitise user inputs**
|
||||
- SQL injections still apply
|
||||
Reference in new issue
Block a user