2010-08-31 78 views
2

我打算编写一个免费版本和完整版本的软件。我希望软件的免费版本存储的信息也可以通过完整版访问(我不想使用内容提供商)。而且我还想确保在软件更新时这些数据不会丢失。我如何实现这一目标?在不同版本的软件上保留持久信息

回答

2

你需要为你的sqlite助手实现onUpgrade的智能方式。

您应始终拥有新的表创建查询,并将其用于升级并传输任何现有数据。注意:onUpgrade方法为sqlite帮助程序对象运行一次,并且需要处理其中的所有表。

所以建议采取什么onUpgrade:

  • 的BeginTransaction
  • 运行与if not exists表生成(我们正在做的升级,因此该表可能还不存在,它将无法修改和删除)
  • 放在一个列表中的现有列List<String> columns = DBUtils.GetColumns(db, TableName);
  • 备份表(ALTER table " + TableName + " RENAME TO 'temp_" + TableName
  • 创建新表(最新表创建模式)
  • 获得与新列的交叉点,从升级后的表采取这一时间列(columns.retainAll(DBUtils.GetColumns(db, TableName));
  • 恢复数据(String cols = StringUtils.join(columns, ","); db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TableName, cols, cols, TableName));
  • 删除备份表(DROP table 'temp_" + TableName
  • setTransactionSuccessful

(这不处理表降级,如果您重命名列,你没有得到转移作为列名不匹配现有的数据)。

public static List<String> GetColumns(SQLiteDatabase db, String tableName) { 
    List<String> ar = null; 
    Cursor c = null; 
    try { 
     c = db.rawQuery("select * from " + tableName + " limit 1", null); 
     if (c != null) { 
      ar = new ArrayList<String>(Arrays.asList(c.getColumnNames())); 
     } 
    } catch (Exception e) { 
     Log.v(tableName, e.getMessage(), e); 
     e.printStackTrace(); 
    } finally { 
     if (c != null) 
      c.close(); 
    } 
    return ar; 
} 

public static String join(List<String> list, String delim) { 
    StringBuilder buf = new StringBuilder(); 
    int num = list.size(); 
    for (int i = 0; i < num; i++) { 
     if (i != 0) 
      buf.append(delim); 
     buf.append((String) list.get(i)); 
    } 
    return buf.toString(); 
} 
+0

我会试试这个并返回给你@Pentium10。感谢名单! – 2010-08-31 12:19:57

+0

在@ Pentium10上为我工作 – 2010-09-08 07:54:31