QT打包Android的资源和打包windows资源的方式不同,像windows中的库,资源,只需要放到工程文件中并配置好正确的路径,就可以被读取到,但是打包成APK之后,资源的路径和windows是不一样的,甚至资源文件都没有被添加到APK中。
首先我们来看看APK的组成。APK本质上也是一个压缩文件,因此也是包含文件路径的。
这里我们拿一个已经生成好的debug APK作为例子看看QT发布的APK包含哪些文件,如下图
可以看到APK内部还是由一系列文件夹构成的,而我们所需要的资源,最终也应该被添加到这些文件夹中(assets文件夹),这样才能在Android程序运行时找到正确的资源路径。
在工程目录android-build文件夹中,也存在一个assets文件夹
但是我们直接将数据库赋值到这个文件夹中,最后打包出来的APK依然是没有包含数据的
因为android-build文件夹是每一次构建时都要重新生成的,也就是说,这些文件是根据我们代码中的配置信息生成,如果代码中没有添加相关的资源信息,那么打包出来的APK依然不会将资源添加进去。
所以需要先修改.pro文件,让系统能自动将我们需要的资源添加到assets文件夹中。
首先,在.pro文件的同级文件夹中新建文件夹database
然后将我们需要的数据库文件添加到database文件夹中
然后需要在.pro文件中添加如下语句
android{ data.files += database/Subjects.db data.path = /assets/database INSTALLS += data }
data.files += 源代码路径下的数据库文件路径
data.path = 编译后存放的文件路径(assets文件夹下的文件,会自动打包到apk)
INSTALLS += 使用INSTALLS将文件复制到输出目录
之后,在点击构建按钮,将会生成一个APK,我们点进这个apk
就可以看到我们需要用的数据已经被添加到这个APK里面了。
最后就是怎么访问数据库了
原理和在windows中访问数据相同,都是需要配置正确的文件路径,其他的就基本上相同了
QSqlDatabase database; if(QSqlDatabase::contains("qt_sql_default_connection")) database = QSqlDatabase::database("qt_sql_default_connection"); else database = QSqlDatabase::addDatabase("QSQLITE"); #ifdef Q_OS_WIN database.setDatabaseName(QApplication::applicationDirPath()+"/"+dbName); #endif #ifdef Q_OS_ANDROID QFile file("assets:/database/Subjects.db"); if(file.exists()) { file.copy("./Subjects.db"); file.setPermissions(QFile::ReadOwner|QFile::WriteOwner); database.setDatabaseName("Subjects.db"); } #endif if (!database.open()) { qDebug() << "Error: Failed to connect database." << database.lastError(); return; }
在语句QFile file("assets:/database/Subjects.db");这个文件路径正好就是我们在APK压缩报截图中,数据库的文件路径,读取到数据库之后,将其拷贝到安卓本地文件系统中读写。
app第一次安装的时候是没有的,所以db不存在,所以会进入if中执行语句,如果你安装好app后,再次打开这个app,系统同样会执行到这里,就不会 进入if中,所以这句话很重要,就是为了 避免每次打开程序,都把app安装包内带有的db文件覆盖到指定地址上。
设置完读写权限之后就可以通过setDatabaseName函数调用数据库了。
除了数据库,其他的资源文件比如图片,字体等等都可以用这样的方式添加到APK中。