【问题标题】:Unity game Sqlite database acts different when running on Android DeviceUnity 游戏 Sqlite 数据库在 Android 设备上运行时表现不同
【发布时间】:2018-10-26 08:33:15
【问题描述】:

我在我的统一项目中实现了一个 SQLite 数据库,它在统一编辑器上运行良好。但是当我在 android 设备上运行它时,数据库操作行为很奇怪。

它有一个主菜单,用户可以从中选择 4 款游戏中的每一款来玩。 我正在计算用户在游戏上花费的总时间。所以我在每个游戏上添加了一个计时器,并将计时器计数推送到数据库中,然后当用户回击时,它会计算总时间的总和。

在 Unity 编辑器中,它在主菜单上完美地显示了最后添加的总时间。 但在 android 中,当用户返回主菜单时,总时间会停止。它不会在android上执行求和操作。

但是当我在同一场景中执行操作时,它也可以在 Android 上运行。

在为 android 编译 SQLite 时,我已正确完成所有操作。我已将我的数据库文件添加到 StreamingAssets 并添加了所有必要的插件。

这是我的代码和文件结构。

定时器.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Data;
using Mono.Data.Sqlite;
using UnityEngine.UI;
using System.IO;

public class Timer : MonoBehaviour {

    public Text timerText;
    private float startTime;

    private string connectionString;

    string minutes;
    string seconds;
    string a;
    float t;

    float DailyTime;

    string CurrentDate;

    // Use this for initialization
    void Start () {
        string filepath = Application.persistentDataPath + "/" + "trackerDB2.sqlite";
        //  // if it doesn't ->

        //  // open StreamingAssets directory and load the db ->

        WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + "trackerDB2.sqlite");  // this is the path to your StreamingAssets in android

        while(!loadDB.isDone) {}  // CAREFUL here, for safety reasons you shouldn't let this while loop unattended, place a timer and error check
        //  // then save to Application.persistentDataPath

        File.WriteAllBytes(filepath, loadDB.bytes);
        connectionString = "URI=file:" + filepath;
        //connectionString = "URI=file:" + Application.dataPath +  "/StreamingAssets/" + "trackerDB2.sqlite";

        startTime = Time.time;



        PlayerPrefs.SetString("date_time", System.DateTime.Now.ToString("yyyy-MM-dd")); 
        CurrentDate = PlayerPrefs.GetString("date_time");
    }

    // Update is called once per frame
    void Update () {
        t = Time.time - startTime;

        //PlayerPrefs.SetFloat ("RowTime",t);

        minutes = ((int)t / 60).ToString ();
        seconds = (t % 60).ToString ("f0");


        PlayerPrefs.SetString ("TimeKey", minutes + ":" + seconds);
        timerText.text =PlayerPrefs.GetString("TimeKey");
        a = minutes;
    }

    public void AddEvent(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("INSERT INTO events(date,timer_count) VALUES({0},{1})",System.DateTime.Now.ToString("yyyy-MM-dd"),t);
                dbCmd.CommandText = sqlQuery;
                dbCmd.ExecuteScalar();
                dbConnection.Close();
            }
        }

        PlayerPrefs.SetString("date_time", System.DateTime.Now.ToString("yyyy-MM-dd")); 
        Debug.Log(PlayerPrefs.GetString("date_time"));
    }

    public void GetSum(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("SELECT SUM(timer_count) FROM events WHERE date={0}",CurrentDate);
                dbCmd.CommandText = sqlQuery;

                using (IDataReader reader = dbCmd.ExecuteReader ()) {
                    while (reader.Read ()) {
                        DailyTime = reader.GetFloat (0);
                    }

                    dbConnection.Close();
                    reader.Close ();
                }


            }
        }

    }

    public void AddDailyEvent(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("UPDATE daily_events SET timer_count={0} WHERE date={1}",DailyTime,CurrentDate);
                dbCmd.CommandText = sqlQuery;
                dbCmd.ExecuteScalar();
                dbConnection.Close();
            }
        }
    }
}

SetDateRow.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Data;
using Mono.Data.Sqlite;
using UnityEngine.UI;
using System.IO;

public class SetDateRow : MonoBehaviour {

    private string connectionString;

    string SqliteDailyDate;
    string SqliteEventsDate;
    float TheTime;

    string CurrentDate;

    public Text DataText;

    // Use this for initialization
    void Start () {
        string filepath = Application.persistentDataPath + "/" + "trackerDB2.sqlite";
        //  // if it doesn't ->

        //  // open StreamingAssets directory and load the db ->

        WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + "trackerDB2.sqlite");  // this is the path to your StreamingAssets in android

        while(!loadDB.isDone) {}  // CAREFUL here, for safety reasons you shouldn't let this while loop unattended, place a timer and error check
        //  // then save to Application.persistentDataPath

        File.WriteAllBytes(filepath, loadDB.bytes);
        connectionString = "URI=file:" + filepath;
        //connectionString = "URI=file:" + Application.dataPath +  "/StreamingAssets/" + "trackerDB2.sqlite";


        AddEvent ();
        AddFirstEvent ();

        PlayerPrefs.SetString("date_time", System.DateTime.Now.ToString("yyyy-MM-dd")); 
        CurrentDate = PlayerPrefs.GetString("date_time");
    }

    // Update is called once per frame
    void Update () {
    //  GetEvent ();
    }

    //Add new event with o timer at the start of the game
    public void AddEvent(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("INSERT INTO events(date,timer_count) VALUES({0},0)",System.DateTime.Now.ToString("yyyy-MM-dd"));
                dbCmd.CommandText = sqlQuery;
                dbCmd.ExecuteScalar();
                dbConnection.Close();
            }
        }

        PlayerPrefs.SetString("date_time", System.DateTime.Now.ToString("yyyy-MM-dd")); 
        Debug.Log(PlayerPrefs.GetString("date_time"));
    }

    //get the last added date of events from daily events table which has the total sum of the time that user played each game
    public void GetDateDailyEvents(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("SELECT date FROM daily_events ORDER BY eventID DESC LIMIT 1");
                dbCmd.CommandText = sqlQuery;

                using (IDataReader reader = dbCmd.ExecuteReader ()) {
                    while (reader.Read ()) {
                        SqliteDailyDate = reader.GetString (0);
                    }

                    dbConnection.Close();
                    reader.Close ();
                }


            }
        }
    }


    //get the last added date from events table which has timer count of each event seperately
    public void GetDateEvents(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("SELECT date FROM events ORDER BY event_id DESC LIMIT 1");
                dbCmd.CommandText = sqlQuery;

                using (IDataReader reader = dbCmd.ExecuteReader ()) {
                    while (reader.Read ()) {
                        SqliteEventsDate = reader.GetString (0);
                    }

                    dbConnection.Close();
                    reader.Close ();
                }


            }
        }
    }


    public void AddFirstEvent(){
        GetDateDailyEvents ();
        GetDateEvents ();
        Debug.Log ("daily" + SqliteDailyDate);
        Debug.Log (SqliteEventsDate);
        //check if the last date of events table is equal to the last date of daily events table.
        if (SqliteDailyDate != SqliteEventsDate) {
            using (IDbConnection dbConnection = new SqliteConnection (connectionString)) {
                dbConnection.Open ();
                //if not equal a new event to daily events table will be added
                using (IDbCommand dbCmd = dbConnection.CreateCommand ()) {
                    string sqlQuery = String.Format ("INSERT INTO daily_events(date,timer_count) VALUES({0},0)", System.DateTime.Now.ToString ("yyyy-MM-dd"));
                    dbCmd.CommandText = sqlQuery;
                    dbCmd.ExecuteScalar ();
                    dbConnection.Close ();
                }
            }

        }


        PlayerPrefs.SetString("date_time", System.DateTime.Now.ToString("yyyy-MM-dd")); 
        Debug.Log(PlayerPrefs.GetString("date_time"));
    }

    public void ShowData(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("SELECT timer_count FROM daily_events WHERE date={0}",SqliteDailyDate);
                dbCmd.CommandText = sqlQuery;

                using (IDataReader reader = dbCmd.ExecuteReader ()) {
                    while (reader.Read ()) {
                        DataText.text = reader.GetFloat (0).ToString();
                    }

                    dbConnection.Close();
                    reader.Close ();
                }


            }
        }
    }


    public void GetEvent(){
        using (IDbConnection dbConnection = new SqliteConnection(connectionString)){
            dbConnection.Open();

            using(IDbCommand dbCmd = dbConnection.CreateCommand()){
                string sqlQuery = String.Format("SELECT timer_count FROM daily_events WHERE date={0}",CurrentDate);
                dbCmd.CommandText = sqlQuery;

                using (IDataReader reader = dbCmd.ExecuteReader ()) {
                    while (reader.Read ()) {
                        DataText.text = reader.GetFloat (0).ToString();
                    }

                    dbConnection.Close();
                    reader.Close ();
                }


            }
        }
    }

}

请帮我解决这个问题。

【问题讨论】:

    标签: c# android unity3d


    【解决方案1】:

    似乎您每次启动时都在重写数据库。

    File.WriteAllBytes(filepath, loadDB.bytes);
    

    我建议添加检查数据库文件是否已存在不要重写它。

    【讨论】:

    • 我添加了一个检查条件,它起作用了。非常感谢。!!
    猜你喜欢
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多