android 对象存储_在Android中存储对象

android 对象存储

android 对象存储

在Android上使用SQLite的一种替代方法是将Java对象存储在SharedPreferences中。 在这里,我们将研究两种不同的方法。

为什么不为所有存储需求选择SQLite? 原因可能多种多样:除了对象定向数据库和关系数据库之间的阻抗不匹配外,对于某些简单的用例,SQLite可能会过大(带来更多开销),或者可能完全不喜欢SQLite的使用和语法。

例如,我们将使用以下User类:

/** User object to be saved in db */
public class User{

    private int id; // used for object storage
    private String userName;
    private boolean registered;
    private double score;

    /** Constructor */
   public User(int id, String userName, boolean registered, double score){
       this.id = id;
       this.userName = userName;
       this.registered = registered;
       this.score = score;
   }
   // getters and setters here...
}

唯一标识符id很可能由我们的服务器分发,尽管一旦我们创建了User并将其单独存储在SharedPreferences中(取决于应用程序的设计),我们也可以在设备本身上对其进行计算。 在这里,我们仅将其用作对象存储密钥。

接下来,我们需要编写我们的首选项类:

/** stores the user object in SharedPreferences */
public class UserPrefs{

    /** This application's preferences label */
    private static final String PREFS_NAME = "com.our.package.UserPrefs";

    /** This application's preferences */
    private static SharedPreferences settings;

   /** This application's settings editor*/
   private static SharedPreferences.Editor editor;

   /** Constructor takes an android.content.Context argument*/
   public UserPrefs(Context ctx){
        if(settings == null){
           settings = ctx.getSharedPreferences(PREFS_NAME, 
                                               Context.MODE_PRIVATE );
        }
       /*
        * Get a SharedPreferences editor instance.
        * SharedPreferences ensures that updates are atomic
        * and non-concurrent
        */
        editor = settings.edit();     
   }
   //...
}

方法1:带有字段键的展平对象

这里的想法是,尽管SharedPreferences仅存储基本类型,但对象构造最终是基本的“包”。 因此,我们可以将一个对象分解为一组原语,并使用唯一键分别存储每个原语。 但是,如果要从存储中重建对象,则确实需要跟踪哪个保存的字段属于哪个对象。

因此,在对UserPrefs类中的给定User对象编写CRUD方法之前,我们需要在每个User类成员上定义唯一键。 为了方便起见,我们可以编写一种方法来确保整个键的唯一性:

/** The prefix for flattened user keys */
public static final String KEY_PREFIX =
            "com.our.package.KEY";

/** Method to return a unique key for any field belonging to a given object
* @param id of the object
* @param fieldKey of a particular field belonging to that object
* @return key String uniquely identifying the object's field
*/
private String getFieldKey(int id, String fieldKey) {
       return  KEY_PREFIX + id + "_" + fieldKey;
}

请注意, getFieldKey()如何为我们提供每个字段名称和每个用户的唯一标识符。

现在,我们可以继续编写CRUD方法:

/** generic field keys */
 private static final String KEY_USERNAME = "com.our.package.KEY_USERNAME";
 private static final String KEY_REGISTERED = "com.our.package.KEY_REGISTERED";
 private static final String KEY_SCORE = "com.our.package.KEY_SCORE";

/** Store or Update */
public void setUser(User user){
    if(user == null)
      return; // don't bother

    int id = user.getId();
    editor.putString(
               getFieldKey(id, KEY_USERNAME),
               user.getUsername() );
    editor.putBoolean(
               getFieldKey(id, KEY_REGISTERED),
               user.isRegistered() );
    editor.putFloat(
               getFieldKey(id, KEY_SCORE),
               user.getScore() );

    editor.commit();
}

/** Retrieve */
public User getUser(int id){
    String name = settings.getString( 
                  getFieldKey(id, KEY_USERNAME), 
                  "" ); // default value
    boolean registered =  settings.getBoolean(
                 getFieldKey(id, KEY_REGISTERED), 
                 false); // default value
    double score =  settings.getFloat(
                 getFieldKey(id, KEY_SCORE), 
                 0); // default value

    return new User(id, name, registered, score);
}

/** Delete */
public void deleteUser(User user){
   if(user == null)
      return; // don't bother

   int id = user.getId();
   editor.remove( getFieldKey(id, KEY_USERNAME) );
   editor.remove( getFieldKey(id, KEY_REGISTERED) ); 
   editor.remove( getFieldKey(id, KEY_SCORE) ); 

   editor.commit();
}

现在,我们可以从应用程序中的任何位置创建,检索,更新和删除任何用户对象:

// get a SharedPreferences instance
UserPrefs prefs = new UserPrefs( this.getApplicationContext() );

// get id from server or local storage
// then find User with that id
User user = prefs.getUser(id);

// operations on User, e.g.
user.setRegistered(true);
user.setScore(new_score);

// save
prefs.setUser(user);
// ...or delete
prefs.deleteUser(user),

对于嵌入式对象,我们递归应用相同的逻辑,并从User CRUD方法中调用其getter / setter方法。 这种扁平化对象的方法是手机上一个简单的,无需SQL的替代存储。 当然,随着嵌入对象数量的增加,它也有其局限性。

方法2:Google Gson

Gson是一个Java库,它提供简单的toJson()fromJson()方法来将Java对象转换为JSON格式,反之亦然。然后,我们只需将JSON格式作为整个String存储在SharedPreferences中。 这种方法涉及到向我们的项目中添加新的库,但是更加方便:

// convert User object user to JSON format
Gson gson = new Gson();
String user_json = gson.toJson(user); 

// store in SharedPreferences 
String id =  "" +  user.getId(); // get storage key
editor.putString(id, user_json);
editor.commit();

// time flies...

// do the reverse operation
 user_json = settings.getString(id, "");
 user  = gson.fromJson(user_json, User.class);

现在可以在我们的UserPrefs类中重写以前的CRUD方法,而无需使用用户ID以外的其他键。 那应该很简单,留给读者作为练习。

结论

我们研究了使用SharedPreferences存储对象的几种方法。 处理对象的其他选项是许多用于Android的ORM ( ORMLitegreenDAOSugar ORMActiveAndroid等),或NOSQL移动数据库,例如Couchbase Lite (此时为Beta版本)。 Couchbase Lite基本上是一个JSON数据库,而当数据模型变得复杂并且我们发现自己编写了大量样板化SQLite操作时,各种ORM可以大大简化我们的代码。 与所有旨在降低底层复杂性的抽象一样,ORM的缺点是泄漏抽象定律

在某种程度上,所有非平凡的抽象都是泄漏的。

ORM和NOSQL替代品将成为后续文章的主题。

参考:来自Tony博客博客的JCG合作伙伴Tony Sicilian在Android中存储对象

翻译自: https://www.javacodegeeks.com/2013/12/storing-objects-in-android.html

android 对象存储

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值