2011-02-10 40 views
6

我一直在研究在转弯之间保存游戏数据的替代方法,并想知道是否有人可以将我指向正确的方向。保存数据的首选方法 - 首选项,sqlite,可序列化或其他?

我有大约32k的数据,必须在onPause期间保存。由于数据量很大,我排除了偏好。我花了几天时间玩SQLite,但不能在不到两秒的时间内保存数据(尽管时间肯定没有浪费)。

我决定在游戏开始时使用数据库加载常量数据。这肯定会让游戏中的各种参数和默认值更容易调整。但是这仍然让我寻找写数据的理想方法。

需要保存的数据基本上是9次出现的A类和9次出现的B类。我是Android的学习曲线的密集月份(以及来自C++背景的Java细微差别)并一直在疯狂地谷歌搜索。这带来了两种可能的头脑 -

1)序列化(ObjectOutputStream的)

我想这将是完美的解决方案,但是,看了关于这个问题的其他几个职位,收集它没有强烈推荐的Android平台由于速度和内存分配而引发垃圾收集器陷入潜在的愤怒。

2)DataOutputStream类类

我现在的想法是加载和保存功能添加到这两个类和使用DataOutputStream类和DataInputStream类中调用它们写入和读取各个数据。

类中的数据是基本类型(主要是字符串和ints)和基元数组,所以没有太多复杂的内容来分解。这第二个解决方案看起来是一个好的,可行的解决方案?还是还有其他解决方案,我还没有意识到?

+0

需要考虑的主要因素是写入闪存可能是一项长期操作,无论数据的大小如何。即使写入1个字节也会花费大量时间。因此,请确保您的解决方案缓冲所有数据并尽可能少地进行操作。 – Jems

+1

感谢您的建议。我已经使用了DataOutputStream方法,写入数据的时间现在可以忽略不计(大约0.1秒)。我很高兴我对SQLite数据库有了一些偏见,因为它们肯定会非常有用:) – Rok

回答

2

您应该使用一个异步任务来保存数据,我用这个方法来获取高分在开始游戏:

new HighscoreTask().execute(this); 

的异步任务看起来是这样的:

public class HighscoreTask extends AsyncTask<MainView, Void, Void> { 

    protected void onPreExecute() { 
    } 

    protected void onPostExecute(final Void unused) { 
    } 
    @Override 
    protected Void doInBackground(MainView... params) { 
     HighScoreFactory.syncScores(); 
     return null; 
    } 
} 

所有数据库交互发生在HighScoreFactory.syncScores()这可以采取只要它需要,因为它发生在后台。在我的情况下,它发送一个HTTP请求到外部服务器并将它们加载到数据库中。它从来没有造成任何问题,并无缝工作。

+0

谢谢 - 我一定会牢记这一点。我现在将游戏数据保存为原始二进制文件,其运行速度很快。但肯定会调查异步,因为现在有几个人已经提出了异步。 – Rok

1

您是否尝试过在事务中将数据插入数据库?

try{ 
db.beginTransaction(); 

//here insert data to database  

db.setTransactionSuccessful(); 
} finally { 
db.endTranscation(); 
} 

这可以加快操作。

+0

我尝试使用事务来完成所有写操作在单个事务中完成的时间点 - 这将时间从8秒减少到2秒。我似乎在那个时候撞到了一堵砖墙,给了或者采取了十分之一秒的时间,不能再降下来。这是我所做的第一个SQLite编码,但我的感觉是我无法更快地获得它(尽管我很乐意被告知不然) – Rok

0

使用Context.openFileOutput(String name,int mode)创建一个新的线程来执行数据写入,并将其作为上下文。然后,您可以使用新线程在后台编写它,并使用Context.openFileInput(String name)作为上下文重新获取它。希望这有助于。

2

为什么你的数据库写入有2秒的限制?如果它纯粹是为了UI响应,那么你可以采取另一种方法。

您实际上不必在方法本身中执行保存,您可以启动实际为您保存的新Thread

private void backgroundSave(){ 
    Thread backgroundThread = new Thread() { 
     @Override 
     public void run() { 
      //do save here 
     } 
    }; 
    backgroundThread.start(); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    backgroundSave(); 
} 

您也可以使用AsyncTask这个。

您可能需要考虑用户在保存完成之前尝试重新启动应用程序的情况,但这应该不会太难考虑。

+1

保存的数据在所有活动中都在不断使用。将保存分配给后台线程的想法听起来很不错,但我还没有时间熟悉解决同步问题。这是我一有机会就一定会看到的东西。现在,我发现我可以在大约0.1秒内将数据写入二进制文件。尽管我很欣赏这个建议。这么多学习,这么短的时间...... :) – Rok