简介
引言
谷歌在今年的I/O大会上发布了新的架构库Android architecture component,为了解决开发者遇到的一些常见问题,推荐遵从以下两个原则构建应用:
1. 关注点分离
尽量避免在Activity或Fragment中编写所有的代码,任何不是处理 UI 或操作系统交互的代码都不应该在这些类中。保持它们尽可能的精简可以避免许多与生命周期有关的问题。
2. model驱动UI
使用持久化的model,因为如果 OS 销毁应用释放资源,用户不用担心丢失数据;而且即使网络连接不可靠或者是断开的,应用仍将继续运行。
为此,推出了新的架构组件来帮助开发者快速搭建满足上述要求的应用,这就是四个新组件LiveDate,ViewModel,Room Persistence,Lifecycles的由来,而此次的重点就是Room。
Room
Room提供了一个SQLite之上的抽象层,使得在充分利用SQLite功能的前提下顺畅的访问数据库。Room中有三个主要的组件:Entity,Database和Dao。
使用方法
gradle配置
打开整个项目的build.gradle,然后添加:
allprojects {
repositories {
jcenter()
//因为GFW的原因,这个网站不一定连的上,参考下文中的问题一
maven { url 'https://maven.google.com' }
}
}
然后在app的build.gradle里添加:
// App Toolkit
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
这样就把所需的库添加到项目中的。
Entity
当一个类用@Entity注解并且被@Database注解中的entities属性所引用,Room就会在数据库中为那个entity创建一张表。
默认Room会为entity中定义的每一个field都创建一个column。如果一个entity中有你不想持久化的field,那么你可以使用@Ignore来注释它们,如下面的代码所示:
@Entity
class User {
@PrimaryKey
public int id;
public String firstName;
public String lastName;
@Ignore
Bitmap picture;
}
要持久化一个field,Room必须有获取它的渠道。你可以把field写成public,也可以为它提供一个setter和getter。如果你使用setter和getter的方式,记住它们要基于Room的Java Bean规范。
Primary key
每个entity必须至少定义一个field作为主键(primary key)。即使只有一个field,你也必须用@PrimaryKey注释这个field。如果你想让Room为entity设置自增ID,你可以设置@PrimaryKey的autoGenerate属性。如果你的entity有一个组合主键,你可以使用@Entity注解的primaryKeys属性,具体用法如下:
@Entity(primaryKeys = {
"firstName", "lastName"})
class User {
public String firstName;
public String lastName;
@Ignore
Bitmap picture;
}
Room默认把类名作为数据库的表名。如果你想用其它的名称,使用@Entity注解的tableName属性,如下:
//SQLite中的表名是大小写敏感的。
@Entity(tableName = "users")
class User {
...
}
和tableName属性类似,Room默认把field名称作为数据库表的column名。如果你想让column有不一样的名称,为field添加@ColumnInfo属性,如下:
@Entity(tableName = "users")
class User {
@PrimaryKey
public int id;
@ColumnInfo(name = "first_name")
public String firstName;
@ColumnInfo(name = "last_name")
public String lastName;
@Ignore
Bitmap picture;
}
Indices 和 uniqueness
为了提高查询的效率,你可能想为特定的字段建立索引。要为一个entity添加索引,在@Entity注解中添加indices属性,列出你想放在索引或者组合索引中的字段。下面的代码片段演示了这个注解的过程:
@Entity(indices = {
@Index("name"), @Index("last_name", "address")})
class User {
@PrimaryKey
public int id;
public String firstName;
public String address;
@ColumnInfo(name = "last_name")
public String lastName;
@Ignore
Bitmap picture;
}
有时候,某个字段或者几个字段必须是唯一的。你可以通过把@Index注解的unique属性设置为true来实现唯一性。下面的代码防止了一个表中的两行数据出现firstName和lastName字段的值相同的情况:
@Entity(indices = {
@Index(value = {
"first_name", "last_name"},
unique = true)})
class User {
@PrimaryKey
public int id;
@ColumnInfo(name =