jskubick

jskubick

Kotlin and Android Development featuring Jetpack: SQLite database not removed by uninstallation of PennyDrop

This isn’t errata per se, but I discovered something unexpected while working through Chapter 5. I’m not sure whether I just misunderstood how SQLite works, or whether it’s a bug in Arctic Fox (Android Studio 2020.3.1 patch 2), the x86 Emulator, or the Android 11 ROM it’s running, but it appears that uninstalling PennyDrop does NOT blow away the underlying SQLite database.

How to replicate:

  1. Build and run PennyDrop in the emulator using the chapter 5 code from the .zip file

  2. Play a game or two, giving the player a distinctive name you’ll recognize later.

  3. Kill PennyDrop in the emulator by clicking the red ‘stop’ icon in Android Studio.

  4. In the Emulator, go to Settings → Apps, find PennyDrop, and uninstall it.

  5. Go back to Android Studio, and re-launch PennyDrop by clicking the green ‘play’ icon. It’ll re-deploy and start.

  6. Attempt to start a new game, and observe it crash with a SQLiteConstraintException (UNIQUE constraint failed on primary key)

It’s been a few years since I’ve used “raw” SQLite, so I don’t remember offhand whether it defaults to putting your database files in the app’s private data dir, or whether the app is expected to tell it where to put them (and the private data dir is simply an obvious & sensible place)… but it looks like Jetpack Room does NOT put its SQLite data files there, and instead puts them somewhere else that doesn’t automatically get blown away when the app gets uninstalled.

Of course, it’s also possible that Google built a custom ROM for the emulator that intentionally leaves the data dir of uninstalled apps behind for forensics purposes, or that it’s actually a developer setting somewhere that I’ve just overlooked for years. It might also be an outright bug in Arctic Fox, or Room 2.3.0, or all the above and more.

Either way, the only solution I’ve found is to modify PennyDropDatabase.kt as follows:

  1. Increase the ‘version’ number in the @Database annotation:
    @Database(
        entities = [Game::class, Player::class, GameStatus::class],
->      version = 2,
        exportSchema = false
    )
  1. Add a call to fallbackToDestructiveMigration() to the builder:
    val instance = Room.databaseBuilder(
        context,
        PennyDropDatabase::class.java,
        "PennyDropDatabase" )
->      .fallbackToDestructiveMigration()
        .addCallback(object : RoomDatabase.Callback() {
        override fun onCreate(db : SupportSQLiteDatabase) {
        // ...

As I understand it, the call to fallbackToDestructiveMigration() basically tells it, “if the database version changes, blow away the old one and rebuild it from scratch according to the new specs without attempting to migrate anything”.

Given everything I’ve always thought I’ve known about the implied behavior of Android apps when uninstalled, the persistence of Room-created SQLite databases after the creator’s uninstallation is pretty shocking, and almost has to be a bug in Room unless it’s just the side effect of a developer option I overlooked. Otherwise, this would leave the door open to a SERIOUS (flash) memory leak for an Android device… a misbehaving app could create a multi-gigabyte Room database that would persist even after the app that created it were uninstalled, and would (AFAIK) be impossible to remove by hand unless the device were rooted.

Update:

According to this post at StackOverflow (android - Remove room database on app uninstall - Stack Overflow), the android:allowBackup=“true” in AndroidManifest.xml might be the root of the problem. Apparently, SQLite databases are one of the things that automatically get backed up.

From what I’ve read so far, once the backup gets made, deleting it is “a pain”, because the backups are almost viral. Merely changing allowBackups to false will prevent future backups, but won’t prevent the existing backup from getting auto-restored in perpetuity upon reinstallation. It looks like the only official way to purge the backup once it has been created is to make the app uninstallation-aware, and add code to the DAO class to explicitly drop the tables as part of the uninstallation process.

Where Next?

Popular Pragmatic Bookshelf topics Top

jeffmcompsci
Title: Design and Build Great Web APIs - typo “https://company-atk.herokuapp.com/2258ie4t68jv” (page 19, third bullet in URL list) Typo:...
New
edruder
I thought that there might be interest in using the book with Rails 6.1 and Ruby 2.7.2. I’ll note what I needed to do differently here. ...
New
gilesdotcodes
In case this helps anyone, I’ve had issues setting up the rails source code. Here were the solutions: In Gemfile, change gem 'rails' t...
New
jskubick
I’m running Android Studio “Arctic Fox” 2020.3.1 Patch 2, and I’m embarrassed to admit that I only made it to page 8 before running into ...
New
brunogirin
When running tox for the first time, I got the following error: ERROR: InterpreterNotFound: python3.10 I realised that I was running ...
New
New
hazardco
On page 78 the following code appears: <%= link_to ‘Destroy’, product, class: ‘hover:underline’, method: :delete, data: { confirm...
New
akraut
The markup used to display the uploaded image results in a Phoenix.LiveView.HTMLTokenizer.ParseError error. lib/pento_web/live/product_l...
New
creminology
Skimming ahead, much of the following is explained in Chapter 3, but new readers (like me!) will hit a roadblock in Chapter 2 with their ...
New
ggerico
I got this error when executing the plot files on macOS Ventura 13.0.1 with Python 3.10.8 and matplotlib 3.6.1: programming_ML/code/03_...
New

Other popular topics Top

AstonJ
If it’s a mechanical keyboard, which switches do you have? Would you recommend it? Why? What will your next keyboard be? Pics always w...
New
siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
AstonJ
poll poll Be sure to check out @Dusty’s article posted here: An Introduction to Alternative Keyboard Layouts It’s one of the best write-...
New
AstonJ
I’ve been hearing quite a lot of comments relating to the sound of a keyboard, with one of the most desirable of these called ‘thock’, he...
New
AstonJ
If you are experiencing Rails console using 100% CPU on your dev machine, then updating your development and test gems might fix the issu...
New
Maartz
Hi folks, I don’t know if I saw this here but, here’s a new programming language, called Roc Reminds me a bit of Elm and thus Haskell. ...
New
foxtrottwist
A few weeks ago I started using Warp a terminal written in rust. Though in it’s current state of development there are a few caveats (tab...
New
First poster: AstonJ
Jan | Rethink the Computer. Jan turns your computer into an AI machine by running LLMs locally on your computer. It’s a privacy-focus, l...
New
Margaret
Ask Me Anything with Mark Volkmann @mvolkmann On February 24 and 25, we are giving you a chance to ask questions of PragProg author M...
New
Fl4m3Ph03n1x
Background Lately I am in a quest to find a good quality TTS ai generation tool to run locally in order to create audio for some videos I...
New

Sub Categories: