我会尽量保持精确.我从我的web服务调用得到一个长base64字符串的响应.我解码字符串并得到一个包含我的数据的巨大字符串.我反序列化字符串并使用如下字符串创建我的类的对象.
String decryptedXml = XmlObject.toDecryptedXmlString(gameDetail.getGameData(),app.getSessionEncryptionKey());Game noviceGame = deserialiseGame(decryptedXml,NoviceGamer.class);
desrialiseGame()只是一种解析数据并创建和返回我的游戏实例的方法.为了将这个对象保持为多个会话(登录/注销),我将我的整个gameData(我的字符串,其反序列化给了我的游戏实例)存储在数据库中.
下次用户登录时,为了创建Game实例,我从我的DB中获取字符串,然后再次尝试反序列化,以便我回到我的Game实例.但是当我尝试从我的数据库中获取字符串时,在获取字符串时我得到“OUT OF MEMORY”异常.
调用游戏反序列化的方法如下.
private HashMap<String,Game> games = new HashMap<String,Game>();public voID load(LocalDatabaseHelper localDbHelper) throws Exception{ synchronized(gameLockObject) { GameDetailDAO dao = new GameDetailDAO(localDbHelper); //this will fetch me the all the entitIEs from databse ArrayList<GameDetailEntity> dbGameDetails = dao.getEntitIEs(null,null); for (GameDetailEntity gameDetail : dbGameDetails) { String gameLevel = gameDetail.getDetailLevel(); String gameXml = gameDetail.getGameData(); Game game = null; if(gameLevel.equalsIgnoreCase("Novice")) { game = Job.deserialiseJob(gameXml,NoviceLevel.class); } else if (gameLevel.equalsIgnoreCase("Expert")) { game = Job.deserialiseJob(gameXml,ExpertLevel.class); } //set the job version game.setGameversion(gameDetail.getGameVersion()); game.setMagicNumber(gameDetail.getMagicNumber()); game.setInactiveUser(gameDetail.getInactiveUser()); game.setStartTime(gameDetail.getStartTime()); game.setFinishTime(gameDetail.getFinishTime()); game.setGameCompletionTime(gameDetail.getGameCompletionTime()); if (!StringUtils.isNullOrEmpty(gameDetail.getGameStatus())) { game.setGameStatus(GameStatus.valueOf(gameDetail.getGameStatus())); } //add the job to the store games.put(gameDetail.getGameRef().tolowerCase(Locale.getDefault()),game); } }}
我的数据库事务如下:
@OverrIDe protected GameEntity getEntityFromCursor(Cursor cursor) { String gameRef = cursor.getString(cursor.getColumnIndex(GAME_REF)); String detailLevel = cursor.getString(cursor.getColumnIndex(DETAIL_LEVEL)); int gameVersion = cursor.getInt(cursor.getColumnIndex(GAME_VERSION)); String gameData = cursor.getString(cursor.getColumnIndex(GAME_DATA)); String status = cursor.getString(cursor.getColumnIndex(GAME_STATUS)); long longStart = cursor.getLong(cursor.getColumnIndex(VISIT_START_TIME)); Date startTime = longStart == -1 ? null : new Date(longStart); long longFinish = cursor.getLong(cursor.getColumnIndex(VISIT_END_TIME)); Date finishTime = longFinish == -1 ? null : new Date(longFinish); long longComplete = cursor.getLong(cursor.getColumnIndex(GAME_COMPLETION_TIME)); Date completionTime = longComplete == -1 ? null : new Date(longComplete); GameEntity entity = new GameEntity(gameRef,detailLevel,gameVersion,gameData,); entity.setGameStatus(status); entity.setStartTime(startTime); entity.setFinishTime(finishTime); entity.setGameCompletionTime(completionTime); return entity; }
但是当我尝试从数据库@line中获取数据时
String gameData = cursor.getString(cursor.getColumnIndex(GAME_DATA));我内存不足错误.根据我的发现,当我在应用程序标记的清单中添加标志largeHeap = true时,我的应用程序变得非常缓慢.还有developer.androID声明
Never request a large heap simply because you’ve run out of memory
and you need a quick fix—you should use it only when you kNow exactly
where all your memory is being allocated and why it must be retained.
Yet,even when you’re confIDent your app can justify the large heap,
you should avoID requesting it to whatever extent possible.
任何人都可以建议我如何避免这种情况.大多数SO问题都没有位图使用.任何帮助将不胜感激.
解决方法 sqlCipher for AndroID为每个光标窗口分配一个内存缓冲区,最大大小为1 MB.由于您评论说游戏数据文件非常大,因此大小可能超过了光标窗口的最大大小,从而导致内存分配错误.在这种情况下,我们可能会推荐以下两个选项之一:>将游戏数据规范化为更典型的数据库结构(即多个表,列,行).>将游戏数据文件拆分成片段,每个片段小于1 MB,然后在应用程序中重新组合它们.
总结以上是内存溢出为你收集整理的android – SQL Cursor在调用getString时抛出内存不足全部内容,希望文章能够帮你解决android – SQL Cursor在调用getString时抛出内存不足所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)