标签:
version 0.89.0
官方文档
工程的build.gradle中添加
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:0.88.3"
}
}
引用module的build.gradle中添加
apply plugin: ‘realm-android‘
-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class * { *; }
-dontwarn javax.**
-dontwarn io.realm.**
必须属性和null值
@Ignore来声明Realm忽略的属性
和ios一样
顾名思义当一个数据的内容改变时,它会自动更新该数据的所有实例化对象
realm.beginTransaction();
Dog myDog = realm.createObject(Dog.class);
myDog.setName("Fido");
myDog.setAge(1);
realm.commitTransaction();
Dog myPuppy = realm.where(Dog.class).equals("age", 1).findFirst();
realm.beginTransaction();
myPuppy.setAge(2);
realm.commitTransaction();
myDog.getAge(); // => 2
当数据变化,需要更新界面时,需要配合 [Realm notifications](#Realm notifications) 实现,后续会详细描述这功能
@Index 来修饰索引类型
索引支持类型
Indexing a property will greatly speed up queries where the property is compared for equality (i.e. the = and IN operators), at the cost of slower insertions.
使用索引增加查询速度的代价是插入数据时速度会降低
@PrimaryKey 用来修饰主键.@PrimaryKey可以修饰String,short,int,long.
@PrimaryKey只能修饰一个属性.
@PrimaryKey声明一个主键后,该属性会被隐性声明成@Index.
@PrimaryKey声明一个主键后,该属性会被隐性声明成@Required,不能为null.
声明主键之后,对象将被允许查询,更新速度更加高效,并且要求每个对象保持唯一性。
一旦带有主键的对象被添加到 Realm 之后,该对象的主键将不可修改。
当调用Realm.createObject(),它会返回一个有默认值的对象,当有主键时,主键会被设置默认值,这样可能会与已有对象冲突.所以最好使用copyToRealm()或者copyToRealmOrUpdate()替换
MyObject obj = new MyObject();
obj.setId(42);
obj.setName("Fish");
realm.beginTransaction();
// This will create a new one in Realm
// realm.copyToRealm(obj);
// This will update a existing one with the same id or create a new one instead
realm.copyToRealmOrUpdate(obj);
realm.commitTransaction();
重写 Object.ignoredProperties() 可以防止 Realm 存储数据模型的某个属性。Realm 将不会干涉这些属性的常规操作,它们将由成员变量(ivar)提供支持,并且您能够轻易重写它们的 setter 和 getter。
class Person: Object {
dynamic var tmpID = 0
var name: String { // read-only properties are automatically ignored
return "\(firstName) \(lastName)"
}
dynamic var firstName = ""
dynamic var lastName = ""
override static func ignoredProperties() -> [String] {
return ["tmpID"]
}
}
Realm不支持final,transient和volatile修饰
public class Email extends RealmObject {
private String address;
private boolean active;
// ... setters and getters left out
}
public class Contact extends RealmObject {
private String name;
private Email email;
// ... setters and getters left out
}
public class Contact extends RealmObject {
private Email email;
// Other fields…
}
如果将email设为null,会断开2个实例间的关系,但是email实例没有被删除
class Person: Object {
public class Contact extends RealmObject {
private RealmList<Email> emails;
// Other fields…
}
}
public class Person extends RealmObject {
private String id;
private String name;
private RealmList<Dog> dogs;
// getters and setters
}
public class Dog extends RealmObject {
private String id;
private String name;
private String color;
// getters and setters
}
// users => [U1,U2]
RealmResults<User> users = realm.where(User.class)
.equalTo("dogs.color", "Brown")
.findAll();
// r1 => [U1,U2]
RealmResults<User> r1 = realm.where(User.class)
.equalTo("dogs.name", "Fluffy")
.equalTo("dogs.color", "Brown")
.findAll();
// r2 => [U2]
RealmResults<User> r2 = realm.where(User.class)
.equalTo("dogs.name", "Fluffy")
.findAll()
.where()
.equalTo("dogs.color", "Brown")
.findAll();
.where()
.equalTo("dogs.color", "Yellow")
.findAll();
所有写入操作(添加,修改,删除)都必须依托一个write transaction.
由于write transaction会占用一定的资源,所以尽量精简write transaction的个数.当队列写入时,只需要一个就write transaction
在UI线程和后台线程同时开始写事务时,会导致ARN
写事务都是线程安全的.
// Obtain a Realm instance
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
//... add or update objects here ...
realm.commitTransaction();
当开始写操作后,可以随时取消
realm.beginTransaction();
User user = realm.createObject(User.class);
// ...
realm.cancelTransaction();
由于RealmObjects必须依赖在Realm,所以其创建方式如下:
realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();
//========other
User user = new User("John");
user.setEmail("john@corporation.com");
// Copy the object to Realm. Any further changes must happen on realmUser
realm.beginTransaction();
User realmUser = realm.copyToRealm(user);
realm.commitTransaction();
当使用realm.copyToRealm后,对原始数据修改,将不会被同步到Realm中.
会自动执行realm.beginTransaction(), realm.commitTransaction()
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.createObject(User.class);
user.setName("John");
user.setEmail("john@corporation.com");
}
});
异步事务,主要是用于大量数据写入
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm bgRealm) {
User user = bgRealm.createObject(User.class);
user.setName("John");
user.setEmail("john@corporation.com");
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
// Transaction was a success.
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
// Transaction failed and was automatically canceled.
}
});
RealmAsyncTask transaction = realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm bgRealm) {
User user = bgRealm.createObject(User.class);
user.setName("John");
user.setEmail("john@corporation.com");
}
}, null);
public void onStop () {
if (transaction != null && !transaction.isCancelled()) {
transaction.cancel();
}
}
通过查询操作,Realm 将会返回包含 Object 集合的Results实例。Results 的表现和 List 十分相似。
所有的查询(包括查询和属性访问)在 Realm 中都是延迟加载的,只有当属性被访问时,才能够读取相应的数据。也就是说当没有使用数据前,进行多次排序或者过滤都是不需要额外cpu时间的
查询结构不是Copy对象,而是引用对象.所以在Write操作中修改查询数据,是直接修改数据库中的数据.
Realm使用Fluent interface,也就是流接口
基本查询语句
// Build the query looking at all users:
RealmQuery<User> query = realm.where(User.class);
// Add query conditions:
query.equalTo("name", "John");
query.or().equalTo("name", "Peter");
// Execute the query:
RealmResults<User> result1 = query.findAll();
// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults<User> result2 = realm.where(User.class)
.equalTo("name", "John")
.or()
.equalTo("name", "Peter")
.findAll();
当查询内容为空时,RealmResults不会为null,它的size==0
主要是or()和not()
not(),用来否定花括号中的条件
流接口中支持”花括号”,beginGroup() => ‘{’ , endGroup() => ‘}’
RealmResults<User> r = realm.where(User.class)
.greaterThan("age", 10) //implicit AND
.beginGroup()
.equalTo("name", "Peter")
.or()
.contains("name", "Jo")
.endGroup()
.findAll();
RealmResults<User> result = realm.where(User.class).findAll();
result.sort("age"); // Sort ascending
result.sort("age", Sort.DESCENDING);
RealmResults<User> teenagers = realm.where(User.class).between("age", 13, 20).findAll();
User firstJohn = teenagers.where().equalTo("name", "John").findFirst();
RealmResults<User> teensWithPups = realm.where(User.class).between("age", 13, 20).equalTo("dogs.age", 1).findAll();
结果会自动更新
RealmResults<Dog> puppies = realm.where(Dog.class).lessThan("age", 2).findAll();
puppies.size(); // => 0
realm.beginTransaction();
Dog dog = realm.createObject(Dog.class);
dog.setName("Fido");
dog.setAge(1);
realm.commitTransaction();
puppies.size(); // => 1
realm.allObjects()
RealmResults<User> results = realm.where(User.class).findAll();
long sum = results.sum("age").longValue();
long min = results.min("age").longValue();
long max = results.max("age").longValue();
double average = results.average("age");
long matches = results.size();
RealmResults<User> results = realm.where(User.class).findAll();
for (User u : results) {
// ... do something with the object ...
}
RealmResults<User> results = realm.where(User.class).findAll();
for (int i = 0; i < results.size(); i++) {
User u = results.get(i);
// ... do something with the object ...
}
// Find all dogs older than or equal to 2 and change their age to 1
RealmResults results = realm.where(Dog.class).greaterThanOrEqualTo("age", 2).findAll();
realm.beginTransaction();
for (int i = results.size() -1; i >=0; i--) {
results.get(i).setAge(1);
}
realm.commitTransaction();
// obtain the results of a query
RealmResults<Dog> results = realm.where(Dog.class).findAll();
// All changes to data must happen in a transaction
realm.beginTransaction();
// remove single match
results.remove(0);
results.removeLast();
// remove a single object
Dog dog = results.get(5);
dog.removeFromRealm();
// Delete all matches
results.clear();
realm.commitTransaction()
private RealmChangeListener callback = new RealmChangeListener() {
@Override
public void onChange() { // called once the query complete and on every update
// use the result
}
};
public void onStart() {
RealmResults<User> result = realm.where(User.class).findAllAsync();
result.addChangeListener(callback);
}
public void onStop () {
result.removeChangeListener(callback); // remove a particular listener
// or
result.removeChangeListeners(); // remove all registered listeners
}
当RealmResults有数据绑定后,result.isLoaded(),会一直返回true
RealmResults<User> result = realm.where(User.class).findAllAsync();
if (result.isLoaded()) {
// Results are now available
}
强制执行异步查询,会阻塞当前线程.
RealmResults<User> result = realm.where(User.class).findAllAsync();
result.load() // be careful, this will block the current thread until it returns
异步查询只能使用在有Looper的线程上,否则会抛出异常.
Realm.setDefaultConfiguration()直接设置默认配置
Realm默认会将文件存储在Context.getFilesDir(),文件路径是无法修改的
// The RealmConfiguration is created using the builder pattern.
// The realm file will be located in Context.getFilesDir() with name "myrealm.realm"
RealmConfiguration config = new RealmConfiguration.Builder(context)
.name("myrealm.realm")
.encryptionKey(getKey())
.schemaVersion(42)
.setModules(new MySchemaModule())
.migration(new MyMigration())
.build();
// Use the config
Realm realm = Realm.getInstance(config);
RealmConfiguration myConfig = new RealmConfiguration.Builder(context)
.name("myrealm.realm").
.schemaVersion(2)
.setModules(new MyCustomSchema())
.build();
RealmConfiguration otherConfig = new RealmConfiguration.Builder(context)
.name("otherrealm.realm")
.schemaVersion(5)
.setModules(new MyOtherSchema())
.build();
Realm myRealm = Realm.getInstance(myConfig);
Realm otherRealm = Realm.getInstance(otherConfig);
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// The realm file will be located in Context.getFilesDir() with name "default.realm"
RealmConfiguration config = new RealmConfiguration.Builder(this).build();
Realm.setDefaultConfiguration(config);
}
}
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Realm realm = Realm.getDefaultInstance();
// ... Do something ...
realm.close();
}
}
内存中的Realms,没有保存在磁盘上.
优点:可以快速的访问数据,而不需要考虑数据持久化的性能开销.内存Realms只会在temp路径里存放几个文件,用来进行线程间数据同步,不会将Realms中任何数据写入磁盘中
不需要建立基于RealmObject类,只需要通过字符串来操作.
主要优势是灵活
RealmConfiguration realmConfig = new RealmConfiguration.Builder(context).build();
DynamicRealm realm = DynamicRealm.getInstance(realmConfig);
// In a DynamicRealm all objects are DynamicRealmObjects
DynamicRealmObject person = realm.createObject("Person");
// All fields are accesssed using strings
String name = person.getString("name");
int age = person.getInt("age");
// An underlying schema still exists, so accessing a field that does not exist
// will throw an exception
person.getString("I don‘t exist");
// Queries stil work normally
RealmResults<DynamicRealmObject> persons = realm.where("Person")
.equalTo("name", "John")
.findAll();
protected Void doInBackground(Void... params) {
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
// ... Use the Realm instance
} finally {
if (realm != null) {
realm.close();
}
}
return null;
}
在有Looper的线程中,应该如下使用:
public class MyThread extends Thread {
private Realm realm;
public void run() {
Looper.prepare();
try {
realm = Realm.getDefaultInstance();
//... Setup the handlers using the Realm instance
Lopper.loop();
} finally {
if (realm != null) {
realm.close();
}
}
}
}
在minSdkVersion >= 19时,可以如下使用:
try (Realm realm = Realm.getDefaultInstance()) {
// No need to close the Realm instance manually
}
在有Looper的线程上(包括UI线程)会自动更新.
可以使用isAutoRefresh()来知晓是否当前Realm是否支持自动刷新
这一章主要是讲多线程开发,大量写入事务最好是放在其他线程中,以防止UI线程被阻塞
只在一个线程中处理所有事情,不需要担心并发和多线程.(然并卵的话)
Realm在多线程处理上不需要使用线程锁,只需要注意写入操作需要在Write事件中.
// in a Fragment or Activity, etc
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// ... boilerplate omitted for brevity
realm = Realm.getDefaultInstance();
// get all the customers
RealmResults<Customer> customers = realm.where(Customer.class).findAllAsync();
// ... build a list adapter and set it to the ListView/RecyclerView/etc
// set up a Realm change listener
changeListener = new RealmChangeListener() {
@Override
public void onChange() {
// This is called anytime the Realm database changes on any thread.
// Please note, change listeners only work on Looper threads.
// For non-looper threads, you manually have to use Realm.refresh() instead.
listAdapter.notifyDataSetChanged(); // Update the UI
}
};
// Tell Realm to notify our listener when the customers results
// have changed (items added, removed, updated, anything of the sort).
customers.addChangeListener(changeListener);
}
// In a background service, in another thread
public class PollingService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Realm realm = Realm.getDefaultInstance();
// go do some network calls/etc and get some data and stuff it into a ‘json‘ var
String json = customerApi.getCustomers();
realm.beginTransaction();
realm.createObjectFromJson(Customer.class, json); // Save a bunch of new Customer objects
realm.commitTransaction();
// At this point, the data in the UI thread is already up to date.
// ...
}
// ...
}
在其他类型的线程上操作,都是基于Snapshots.
UI线程或者其他添加Runloop的线程上,数据都会自动刷新,除非将Realm.autorefresh设置为NO
其他类型的线程,都是以最后一次修改成功的Realm为snapshot,除非是手动refresh
Realm, RealmObject or RealmResults不能进行多线程传递.
最好使用asynchronous query和asynchronous transaction
```
##Schemas
可以让Realm只包含特定类型.
// Create the module
@RealmModule(classes = { Person.class, Dog.class })
public class MyModule {
}
// Set the module in the RealmConfiguration to allow only classes defined by the module.
RealmConfiguration config = new RealmConfiguration.Builder(context)
.setModules(new MyModule())
.build();
// It is possible to combine multiple modules to one schema.
RealmConfiguration config = new RealmConfiguration.Builder(context)
.setModules(new MyModule(), new MyOtherModule())
.build();
###Sharing schemas
```基于Library开发时,需要注意Realm必须expose并且Realm必须设置对应的schema.
如果不设置schema,当你使用它们时,会抛出异常.
<div class="se-preview-section-delimiter"></div>
// Library must create a module and set library = true. This will prevent the default
// module from being created.
// allClasses = true can be used instead of listing all classes in the library.
@RealmModule(library = true, allClasses = true)
public class MyLibraryModule {
}
// Library projects are therefore required to explicitly set their own module.
RealmConfiguration libraryConfig = new RealmConfiguration.Builder(context)
.name("library.realm")
.setModules(new MyLibraryModule())
.build();
// Apps can add the library RealmModule to their own schema.
RealmConfiguration config = new RealmConfiguration.Builder(context)
.name("app.realm")
.setModules(Realm.getDefaultModule(), new MyLibraryModule())
.build();
<div class="se-preview-section-delimiter"></div>
支持导入类型String,JSONObject,JSONArray和InputStream.
// A RealmObject that represents a city
public class City extends RealmObject {
private String city;
private int id;
// getters and setters left out ...
}
// Insert from a string
realm.beginTransaction();
realm.createObjectFromJson(City.class, "{ city: \"Copenhagen\", id: 1 }");
realm.commitTransaction();
// Insert from a JSONObject
realm.beginTransaction();
realm.createObjectFromJson(City.class, jsonObject);
realm.commitTransaction();
// Insert from a JSONArray
realm.beginTransaction();
realm.createObjectFromJson(City.class, jsonArray);
realm.commitTransaction();
// Insert multiple items using a InputStream
InputStream is = new FileInputStream(new File("path_to_file"));
realm.beginTransaction();
try {
realm.createAllFromJson(City.class, is);
realm.commitTransaction();
} catch (IOException e) {
realm.cancelTransaction();
}
<div class="se-preview-section-delimiter"></div>
修改Listeners只会在有Looper的线程(包含UI线程)中回调,其他线程只能使用Realm.refresh()来刷新
在多线程中修改数据,有Looper的线程(包含UI线程)都会收到Listeners的回调
public class MyActivity extends Activity {
private Realm realm;
// A reference to RealmChangeListener needs to be held to avoid being
// removed by the garbage collector.
private RealmChangeListener realmListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
realm = Realm.getDefaultInstance();
reamlListener = new RealmChangeListener() {
@Override
public void onChange() {
// ... do something with the updates (UI, etc.) ...
}};
realm.addChangeListener(realmListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
// Remove the listener.
realm.removeChangeListener(realmListener);
// Close the realm instance.
realm.close();
}
}
<div class="se-preview-section-delimiter"></div>
关闭所有Listeners
realm.removeAllChangeListeners();
<div class="se-preview-section-delimiter"></div>
RealmObject和RealmResults都可以添加Listeners
public class MyActivity extends Activity {
private Realm realm;
private RealmChangeListener puppiesListener;
private RealmChangeListener dogListener;
private RealmResults<Dog> puppies;
private Dog dog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
realm = Realm.getDefaultInstance();
puppiesListener = new RealmChangeListener() {
@Override
public void onChange() {
// ... do something with the updated puppies instance
}};
// Find all the puppies
puppies = realm.where(Dog.class).lessThanOrEqualTo("age", 2).findAll();
puppies.addChangeListener(puppiesListener);
dogListener = new RealmChangeListener() {
@Override
public void onChange() {
// ... do something with the updated Dog instance
}};
dog = realm.where(Dog.class).equals("name", "Fido").findFirst();
dog.addChangeListener(dogListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
// Remove the listeners
puppies.removeChangeListener(puppiesListener);
dog.removeChangeListener(dogListener);
// Close the realm instance.
realm.close();
}
}
<div class="se-preview-section-delimiter"></div>
给类添加Listeners
Person person = realm.where(Person.class).findFirst();
person.getDogs(); // => 2 - Assume there are 2 dogs in the list
person.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
// React to the change in the Person instance.
// This will also get called when any referenced dogs are updated.
}
});
Dog dog = person.getDogs().get(0);
realm.beginTransaction();
dog.setAge(5);
realm.commitTransaction();
// Person change listener is called on the next iteration of the run loop because
// a referenced dog object changed.
<div class="se-preview-section-delimiter"></div>
数据迁移,版本迭代时,数据库常用
class Person: Object {
dynamic var firstName = ""
dynamic var lastName = ""
dynamic var age = 0
}
<div class="se-preview-section-delimiter"></div>
在某个版本更新中,变成了下边这样
class Person: Object {
dynamic var fullName = ""
dynamic var age = 0
}
<div class="se-preview-section-delimiter"></div>
那么就需要用到数据迁移了.
需要考虑跨版本的数据库迁移,例如v0直接升级到v3版本,而不是只考虑v2升级到v3.
// Example migration adding a new class
RealmMigration migration = new RealmMigration() {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
// During a migration, a DynamicRealm is exposed. A DynamicRealm is an untyped variant of a normal Realm, but
// with the same object creation and query capabilities.
// A DynamicRealm uses Strings instead of Class references because the Classes might not even exist or have been
// renamed.
// Access the Realm schema in order to create, modify or delete classes and their fields.
RealmSchema schema = realm.getSchema();
/************************************************
// Version 0
class Person
@Required
String firstName;
@Required
String lastName;
int age;
// Version 1
class Person
@Required
String fullName; // combine firstName and lastName into single field.
int age;
************************************************/
// Migrate from version 0 to version 1
if (oldVersion == 0) {
RealmObjectSchema personSchema = schema.get("Person");
// Combine ‘firstName‘ and ‘lastName‘ in a new field called ‘fullName‘
personSchema
.addField("fullName", String.class, FieldAttribute.REQUIRED)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
obj.set("fullName", obj.getString("firstName") + " " + obj.getString("lastName"));
}
})
.removeField("firstName")
.removeField("lastName");
oldVersion++;
}
/************************************************
// Version 2
class Pet // add a new model class
@Required
String name;
@Required
String type;
class Person
@Required
String fullName;
int age;
RealmList<Pet> pets; // add an array property
************************************************/
// Migrate from version 1 to version 2
if (oldVersion == 1) {
// Create a new class
RealmObjectSchema petSchema = schema.create("Pet")
.addField("name", String.class, FieldAttribute.REQUIRED)
.addField("type", String.class, FieldAttribute.REQUIRED);
// Add a new field to an old class and populate it with initial data
schema.get("Person")
.addRealmListField("pets", petSchema)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
if (obj.getString("fullName").equals("JP McDonald")) {
DynamicRealmObject pet = realm.createObject("Pet");
pet.setString("name", "Jimbo");
pet.setString("type", "dog");
obj.getList("pets").add(pet);
}
}
});
oldVersion++;
}
/************************************************
// Version 3
class Pet
@Required
String name;
int type; // type becomes int
class Person
String fullName; // fullName is nullable now
RealmList<Pet> pets; // age and pets re-ordered (no action needed)
int age;
************************************************/
// Migrate from version 2 to version 3
if (oldVersion == 2) {
RealmObjectSchema personSchema = schema.get("Person");
personSchema.setNullable("fullName", true); // fullName is nullable now.
// Change type from String to int
schema.get("Pet")
.addField("type_tmp", int.class)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
String oldType = obj.getString("type");
if (oldType.equals("dog")) {
obj.setLong("type_tmp", 1);
} else if (oldType.equals("cat")) {
obj.setInt("type_tmp", 2);
} else if (oldType.equals("hamster")) {
obj.setInt("type_tmp", 3);
}
}
})
.removeField("type")
.renameField("type_tmp", "type");
oldVersion++;
}
}
<div class="se-preview-section-delimiter"></div>
Realm的加密方式为:key为64字节,AES-256
加密过的 Realm 只会带来很少的额外资源占用(通常最多只会比平常慢10%)
注:如果数据库加密后,由于不知道加密方式,即使有原始key,也无法获取解密key,所以无法用Realm Browser查看.
注:如果数据库加密,每次获取Realm实例时,必须使用encryptionKey.
byte[] key = new byte[64];
new SecureRandom().nextBytes(key);
RealmConfiguration config = new RealmConfiguration.Builder(context)
.encryptionKey(key)
.build();
Realm realm = Realm.getInstance(config);
<div class="se-preview-section-delimiter"></div>
GSON is a library created by Google for deserializing and serializing JSON. When using Realm with GSON 2.3.1 (latest version), you have to specify an ExclusionStrategy.
// Using the User class
public class User extends RealmObject {
private String name;
private String email;
// getters and setters left out ...
}
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.create();
String json = "{ name : ‘John‘, email : ‘john@corporation.com‘ }";
User user = gson.fromJson(json, User.class);
<div class="se-preview-section-delimiter"></div>
uses GSON internally, it also needs a properly configured GsonConverter if you want to deserialize network JSON data to RealmObjects.
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.create();
// Configure Retrofit to use the proper GSON converter
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.setConverter(new GsonConverter(gson))
.build();
GitHubService service = restAdapter.create(GitHubService.class);
<div class="se-preview-section-delimiter"></div>
With Retrofit 2, GSON is no longer used by default, but can be used via its converter module.
dependencies {
compile ‘com.squareup.retrofit2:retrofit:2.0.0-beta3‘
compile ‘com.squareup.retrofit2:converter-gson:2.0.0-beta3‘
<div class="se-preview-section-delimiter"></div>
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create(gson)
.build();
标签:
原文地址:http://blog.csdn.net/h48582291/article/details/51195577