Большинство руководств по этой теме устарели.
Посмотрел код и обнаружил несколько проблем, но я не могу сказать, является ли это причиной того, что вы получаете эту ошибку.WWW
следует использовать в функции сопрограммы, чтобы можно было завершить или дождаться окончания loadDb.isDone
, добавив yield return null
внутри цикла while
.Вы также можете выдать запрос WWW
, и этот метод я буду использовать в своем ответе.
Кроме того, jar:file://" + Application.dataPath
- старый код.Для этого используйте Application.streamingAssetsPath
.Кроме того, вам не нужно "URI=file:" + Application.dataPath
.Просто используйте Application.persistentDataPath
для этого.
Я просто добавлю инструкцию о том, как выполнить настройку.
Настройка части кода MANAGED:
1 . Перейдите на путь установки Unity
<UnityInstallationDirecory>\Editor\Data\Mono\lib\mono\2.0
Скопируйте следующие файлы:
I18N.MidEast.dll
I18N.Other.dll
I18N.Rare.dll
I18N.West.dll
Mono.Data.Sqlite.dll
Mono.Data.SqliteClient.dll
System.Data.dll
до проекта<ProjectName>\Assets\Plugins
путь.
Это позволит вам без каких-либо ошибок скомпилировать API из пространства имен Mono.Data.Sqlite
.
Настройка части кода НЕПРАВИЛЬНО:
На этом этапе вам нужно получить нативную библиотеку Sqlite.Вы можете получить исходный код , собрать его и использовать или использовать уже скомпилированный binray.
1 . Получить собственную библиотеку для Windows
Загрузите предварительно скомпилированный бит sqlite3.dll
для Windows 64 из здесь и поместите его в путь <ProjectName>\Assets\Plugins\x86_64
.
Если используется 32-разрядная версия Windows, тогда получите sqlite3.dll
версию из здесь и поместите ее в путь <ProjectName>\Assets\Plugins\x86
.
2 . Получите собственную библиотеку для Android
Загрузите предварительно скомпилированный libsqlite3.so
для процессора Android ARM с здесь и поместите его в путь <ProjectName>\Assets\Plugins\Android\libs\armeabi-v7a
.
Загрузите предварительно скомпилированный libsqlite3.so
для Android-процессор Intel x86 с здесь и поместите его в путь <ProjectName>\Assets\Plugins\Android\libs\x86
.
Это охватывает большинство процессоров , используемых на устройствах Android.
3 . Получите собственную библиотеку для UWP
A . Загрузите папку WSA, затем поместите папку WSA в путь <ProjectName>\Assets\Plugins
.Эта папка содержит исходную часть.
B . Создайте 2 файла с именами "mcs.rsp" и "csc.rsp" в<ProjectName>\Assets
путь.
C . Добавьте следующее в файлы "mcs.rsp" и "csc.rsp" :
-r:I18N.MidEast.dll
-r:I18N.Other.dll
-r:I18N.Rare.dll
-r:I18N.West.dll
-r:Mono.Data.Sqlite.dll
-r:Mono.Data.SqliteClient.dll
-r:System.Data.dll
D . При сборке для UWP вам придется переместить управляемые библиотеки в папку root проекта.Итак, переместите I18N.MidEast.dll
, I18N.Other.dll
, I18N.Rare.dll
, I18N.West.dll
, Mono.Data.Sqlite.dll
, Mono.Data.SqliteClient.dll
, System.Data.dll
на путь <ProjectName>
, а не <ProjectName>\Assets\Plugins
.
4 . Для iOS, Linux и Mac похоже, что вам не нужно ничего загружать для них или делать этот шаг.Как правило, они имеют встроенные встроенные библиотеки Sqlite.
Включение файла базы данных в сборку:
1 . Создайте папку в папке <ProjectName>\Assets
и назовите ее StreamingAssets .Правописание считается, и оно чувствительно к регистру.
2 . Поместите файл базы данных (TBLDatabase.db
) в эту папку StreamingAssets .
Доступ к файлу базы данных после сборки проекта
Sqlite не может работать с файлами в папке StreamingAssets в сборке, поскольку это путь только для чтения.Кроме того, Android требует использования WWW
API вместо стандартного System.IO
API для чтения из папки StreamingAssets .Вам необходимо скопировать файл db из Application.streamingAssetsPath/filename.db
в Application.persistentDataPath/filename.db
.
На некоторых платформах необходимо создать папку внутри Application.persistentDataPath
и вместо этого сохранить данные в эту папку.Всегда делай это.Папка в приведенном ниже примере кода представляет собой «данные», поэтому она станет Application.persistentDataPath/data/filename.db
.
3 . Из-за приведенного выше утверждения проверьте, существует ли файл базы данных вApplication.persistentDataPath/data/filename.db
.Если это так, используйте Application.persistentDataPath/data/filename.db
в качестве пути для вашей базы данных.Если этого не произойдет, продолжите с # 4.
4 . Прочтите и скопируйте файл базы данных из папки StreamingAssets в Application.persistentDataPath
На некоторых платформах необходимо создать папку внутри Application.persistentDataPath
и вместо этого сохранить данные в эту папку.Всегда делай это.В приведенном ниже примере папка «data».
Определите, является ли это Android, и используйте WWW
для чтения файла из Application.streamingAssetsPath/filename.db
.Используйте File.ReadAllBytes
, чтобы прочитать его на другом устройстве, кроме Android.В вашем примере вы использовали Application.platform
для этого.В моем примере я просто проверю, содержит ли путь "://"
или :///
для этого.
5 . Как только вы прочитаете файл, запишите данные, которые вы только что прочиталиApplication.persistentDataPath/data/filename.db
с File.WriteAllBytes
.Теперь вы можете использовать этот путь для вашей операции с базой данных.
6 . Префикс "URI=file:"
к пути Application.persistentDataPath/data/filename.db
, и это путь, который следует использовать в вашей операции с базой данных сAPI Sqlite.
Очень важно, чтобы вы понимали все это, чтобы исправить это, когда что-то меняется, но я уже проделал шаги с # 3 до # 6 ниже.
IEnumerator RunDbCode(string fileName)
{
//Where to copy the db to
string dbDestination = Path.Combine(Application.persistentDataPath, "data");
dbDestination = Path.Combine(dbDestination, fileName);
//Check if the File do not exist then copy it
if (!File.Exists(dbDestination))
{
//Where the db file is at
string dbStreamingAsset = Path.Combine(Application.streamingAssetsPath, fileName);
byte[] result;
//Read the File from streamingAssets. Use WWW for Android
if (dbStreamingAsset.Contains("://") || dbStreamingAsset.Contains(":///"))
{
WWW www = new WWW(dbStreamingAsset);
yield return www;
result = www.bytes;
}
else
{
result = File.ReadAllBytes(dbStreamingAsset);
}
Debug.Log("Loaded db file");
//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(dbDestination)))
{
Directory.CreateDirectory(Path.GetDirectoryName(dbDestination));
}
//Copy the data to the persistentDataPath where the database API can freely access the file
File.WriteAllBytes(dbDestination, result);
Debug.Log("Copied db file");
}
try
{
//Tell the db final location for debugging
Debug.Log("DB Path: " + dbDestination.Replace("/", "\\"));
//Add "URI=file:" to the front of the url beore using it with the Sqlite API
dbDestination = "URI=file:" + dbDestination;
//Now you can do the database operation below
//open db connection
var connection = new SqliteConnection(dbDestination);
connection.Open();
var command = connection.CreateCommand();
Debug.Log("Success!");
}
catch (Exception e)
{
Debug.Log("Failed: " + e.Message);
}
}
Использование :
string dbFileName = "TBLDatabase.db";
void Start()
{
StartCoroutine(RunDbCode(dbFileName));
}