0

I've built an app using Flutter and SQFlite to persist data. I have a database client file, in which there are the key functions to get it to create and initiate the database etc.

To create the database:

  /// Creating the database values
  static final DatabaseClient instance = DatabaseClient._init();
  static Database? _database;
  DatabaseClient._init();

To call the database:

  /// Calling the database
  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('database.db');
    return _database!;
  }

To initiate or open the database:

  /// Future function to open the database
  Future<Database> _initDB(String filePath) async {
    final path = await getDatabasesPath();
    final dbPath = join(path, filePath);
    return await openDatabase(dbPath,
        version: 2, onCreate: _create, onUpgrade: _onUpgrade);
  }

I've also created a function to read all the entries within the database, to show with a ListView type widget:

  /// WB
  Future<List<WBCalcResult>> readAllNotesWB() async {
    final db = await instance.database;
    final orderBy =
        '${WBCalcResultFields.wbDate} DESC ,${WBCalcResultFields.wbTime} DESC';
    final result = await db.query(wbCalcResults, orderBy: orderBy);
    return result.map((json) => WBCalcResult.fromJson(json)).toList();
  }

Then, the function that gets this data from the database in the screen that displays the ListView widget looks like this:

  /// Function to get the info from the database
  Future<void> refreshWBCalcResults() async {
    setState(() => isLoading = true);
    this.wbCalcResults = await DatabaseClient.instance.readAllNotesWB();
    setState(() {});
    setState(() => isLoading = false);
  }

This all works perfectly on both the Android Emulator and iOS simulator.

However, it does not seem to work at all on a physical Android device (it probably doesn't work on a physical iOS device either, although I don't have one to test it with). When I say 'it doesn't work' essentially all I am looking at is a blank screen, where the ListView should be. I can't see an error, or the app freezing or anything like that.

I read it could be to do with resources being shrunk in the release version of a Flutter app messing up the database path finder, so I updated my build.gradle file to prevent resources being shrunk:

buildTypes {
    release {
        signingConfig signingConfigs.release
        shrinkResources false
    }
}

Sadly, none of this seems to be working. My app's SQFlite still will not work in the release versions on physical devices, whilst it still does in debug simulator versions. It did, however, in the first release version that I released for testing.

I am using the latest versions of all the relevant packages, including path_provider (2.0.8)

Can anyone suggest why this might be happening to the release version of my app? What can I do to sort it? Thanks.

James
  • 669
  • 1
  • 10
  • 21

1 Answers1

0

Answer that helped me: https://stackoverflow.com/a/54267755/2866570

I ran flutter with verbose logging on: flutter run -v -d .... It showed exactly what was causing the issue.

In my case I have changed the default package of my application in the manifest file but haven't changed the directory names of the MainActivity.kt file.

Error

[        ] E/AndroidRuntime(12376): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{io.answer.hello/io.answer.hello.MainActivity}: 
java.lang.ClassNotFoundException: Didn't find class "io.answer.hello.MainActivity"
on path: DexPathList[[zip file

My git diff

diff --git a/android/app/src/main/kotlin/com/example/my_app/MainActivity.kt b/android/app/src/main/kotlin/io/answer/hello/MainActivity.kt
similarity index 75%
rename from android/app/src/main/kotlin/com/example/my_app/MainActivity.kt
rename to android/app/src/main/kotlin/io/answer/hello/MainActivity.kt
index a310df9..8920150 100644
--- a/android/app/src/main/kotlin/com/example/my_app/MainActivity.kt
+++ b/android/app/src/main/kotlin/io/answer/hello/MainActivity.kt
@@ -1,4 +1,4 @@
-package com.example.my_app
+package io.answer.hello

My AndroidManifest.xml starts with:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="io.answer.hello">

Note that I have changed the package name in this answer to a fake one.

zaynetro
  • 2,298
  • 20
  • 28
  • Thanks so much @zaynetro for the input. As it happens, I seemed to get to the bottom of the issue (not finding a solution, but at least identifying the issue). This was the second version of my app and compared to the first version, I had used the `onUpgrade` SQFlite function to add a new table. However, it seems as though the way I did it was the issue. When I created a new database, instead of trying to update the current one, it worked fine. – James Jan 17 '22 at 20:03
  • So it seems as though I need to find a way of correcting the `onUpgrade` code I used, to add a new table to the existing database. – James Jan 17 '22 at 20:04