Docs 菜单
Docs 主页
/ /
Atlas Device SDKs

快速入门 - Java SDK

在此页面上

  • 初始化 Realm
  • 定义对象模型
  • 打开 Realm
  • 创建、读取、更新和删除对象
  • 注意更改
  • 完整示例
  • 输出

提示

本指南不使用 Device Sync

本指南可以帮助您开始使用 设备本地Realm。 如果您的应用程序需要使用 Atlas Device Sync 、 Realm Functions 或用户管理等功能通过网络与后端应用进行通信,则应遵循Sync 快速入门指南。

此页面包含快速将 Realm 集成到您的应用程序中的信息。 开始之前,请确保您已:

  • 已安装 Java SDK

在应用程序中使用 Realm 之前,您必须初始化 Realm 库。 您的应用程序应该在每次运行时初始化 Realm 一次。

要初始化Realm库,请为Realm.init()静态函数提供一个 Android context 。 您可以提供活动、片段或应用程序context进行初始化,而行为不会有任何差异。 您可以在 应用程序子类onCreate() 方法中初始化Realm库 以确保每次应用程序运行时仅初始化Realm一次。

Realm.init(this); // context, usually an Activity or Application
Realm.init(this) // context, usually an Activity or Application

提示

在 Android 清单中注册您的应用程序子类

如果创建自己的Application子类,则必须将其添加到应用程序的AndroidManifest.xml中才能执行自定义应用程序逻辑。 设置清单应用程序定义的android.name属性,确保当用户启动您的应用程序时,Android 会先于任何其他类实例化您的Application子类。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mongodb.example">
<application
android:name=".MyApplicationSubclass"
...
/>
</manifest>

应用程序的数据模型定义了Realm中存储的数据结构。 您可以使用Realm对象模型通过应用程序代码中的Kotlin或Java类来定义应用程序的数据模型模型。

要定义应用程序的数据模型,请将以下类定义添加到应用程序代码中:

Task.java
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.Required;
public class Task extends RealmObject {
@PrimaryKey private String name;
@Required private String status = TaskStatus.Open.name();
public void setStatus(TaskStatus status) { this.status = status.name(); }
public String getStatus() { return this.status; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Task(String _name) { this.name = _name; }
public Task() {}
}
TaskStatus.java
public enum TaskStatus {
Open("Open"),
InProgress("In Progress"),
Complete("Complete");
String displayName;
TaskStatus(String displayName) {
this.displayName = displayName;
}
}
Task.kt
enum class TaskStatus(val displayName: String) {
Open("Open"),
InProgress("In Progress"),
Complete("Complete"),
}
open class Task() : RealmObject() {
@PrimaryKey
var name: String = "task"
@Required
var status: String = TaskStatus.Open.name
var statusEnum: TaskStatus
get() {
// because status is actually a String and another client could assign an invalid value,
// default the status to "Open" if the status is unreadable
return try {
TaskStatus.valueOf(status)
} catch (e: IllegalArgumentException) {
TaskStatus.Open
}
}
set(value) { status = value.name }
}

使用RealmConfiguration控制要打开的域的细节,包括域的名称或位置、是否允许在用户界面线程上同步读取或写入域等等。

String realmName = "My Project";
RealmConfiguration config = new RealmConfiguration.Builder().name(realmName).build();
Realm backgroundThreadRealm = Realm.getInstance(config);
val realmName: String = "My Project"
val config = RealmConfiguration.Builder().name(realmName).build()
val backgroundThreadRealm : Realm = Realm.getInstance(config)

打开域后,您可以在 写事务(write transaction) 区块中修改该域内的 对象

重要

UI 线程上的同步读写

默认情况下,只能使用异步事务在应用程序的用户界面线程中读取或写入域。也就是说,除非您明确允许使用同步方法,否则您只能在 Android 应用程序的主线程中使用名称以单词 Async 结尾的 Realm 方法。

此限制是为了应用程序用户的利益:在 UI 线程上执行读写操作,可能导致 UI 交互无响应或速度缓慢,所以通常来说,最好以异步方式或在后台线程中处理这些操作。但是,如果应用程序需要在 UI 线程上使用同步 Realm 读取或写入,则可以通过以下 SyncConfiguration 选项明确支持使用同步方法:

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread."
);
}
});
val config = SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm with reads and writes allowed on the UI thread.")
}
})

要创建新的Task ,请实例化Task类的实例并将其添加到写入区块中的 Realm:

Task Task = new Task("New Task");
backgroundThreadRealm.executeTransaction (transactionRealm -> {
transactionRealm.insert(Task);
});
val task : Task = Task()
task.name = "New Task"
backgroundThreadRealm.executeTransaction { transactionRealm ->
transactionRealm.insert(task)
}

您可以检索域中所有项目的实时集合

// all Tasks in the realm
RealmResults<Task> Tasks = backgroundThreadRealm.where(Task.class).findAll();
// all tasks in the realm
val tasks : RealmResults<Task> = backgroundThreadRealm.where<Task>().findAll()

您还可以使用过滤过滤该集合

// you can also filter a collection
RealmResults<Task> TasksThatBeginWithN = Tasks.where().beginsWith("name", "N").findAll();
RealmResults<Task> openTasks = Tasks.where().equalTo("status", TaskStatus.Open.name()).findAll();
// you can also filter a collection
val tasksThatBeginWithN : List<Task> = tasks.where().beginsWith("name", "N").findAll()
val openTasks : List<Task> = tasks.where().equalTo("status", TaskStatus.Open.name).findAll()

要修改任务,请在写事务区块中更新其属性:

Task otherTask = Tasks.get(0);
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerOtherTask = transactionRealm.where(Task.class).equalTo("_id", otherTask.getName()).findFirst();
innerOtherTask.setStatus(TaskStatus.Complete);
});
val otherTask: Task = tasks[0]!!
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerOtherTask : Task = transactionRealm.where<Task>().equalTo("name", otherTask.name).findFirst()!!
innerOtherTask.status = TaskStatus.Complete.name
}

最后,您可以通过在写事务(write transaction)区块中调用deleteFromRealm()方法来删除除任务:

Task yetAnotherTask = Tasks.get(0);
String yetAnotherTaskName = yetAnotherTask.getName();
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerYetAnotherTask = transactionRealm.where(Task.class).equalTo("_id", yetAnotherTaskName).findFirst();
innerYetAnotherTask.deleteFromRealm();
});
val yetAnotherTask: Task = tasks.get(0)!!
val yetAnotherTaskName: String = yetAnotherTask.name
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerYetAnotherTask : Task = transactionRealm.where<Task>().equalTo("name", yetAnotherTaskName).findFirst()!!
innerYetAnotherTask.deleteFromRealm()
}

您可以通过使用addChangeListener()方法附加自定义OrderedRealmCollectionChangeListener监视域、集合或对象的更改

// all Tasks in the realm
RealmResults<Task> Tasks = uiThreadRealm.where(Task.class).findAllAsync();
Tasks.addChangeListener(new OrderedRealmCollectionChangeListener<RealmResults<Task>>() {
@Override
public void onChange(RealmResults<Task> collection, OrderedCollectionChangeSet changeSet) {
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
OrderedCollectionChangeSet.Range[] deletions = changeSet.getDeletionRanges();
for (OrderedCollectionChangeSet.Range range : deletions) {
Log.v("QUICKSTART", "Deleted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1));
}
OrderedCollectionChangeSet.Range[] insertions = changeSet.getInsertionRanges();
for (OrderedCollectionChangeSet.Range range : insertions) {
Log.v("QUICKSTART", "Inserted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
OrderedCollectionChangeSet.Range[] modifications = changeSet.getChangeRanges();
for (OrderedCollectionChangeSet.Range range : modifications) {
Log.v("QUICKSTART", "Updated range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
}
});
// all tasks in the realm
val tasks : RealmResults<Task> = realm.where<Task>().findAllAsync()
tasks.addChangeListener(OrderedRealmCollectionChangeListener<RealmResults<Task>> { collection, changeSet ->
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
val deletions = changeSet.deletionRanges
for (i in deletions.indices.reversed()) {
val range = deletions[i]
Log.v("QUICKSTART", "Deleted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val insertions = changeSet.insertionRanges
for (range in insertions) {
Log.v("QUICKSTART", "Inserted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val modifications = changeSet.changeRanges
for (range in modifications) {
Log.v("QUICKSTART", "Updated range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
})

如果您在新的 Android Studio 项目中运行此项目,则可以将此文件复制并粘贴到应用程序的MainActivity中,但请记住:

  • 在文件顶部为您自己的项目使用包声明

  • 如果您使用的是 Java,请更新TaskTaskStatusimport语句

Task.java
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.Required;
public class Task extends RealmObject {
@PrimaryKey private String name;
@Required private String status = TaskStatus.Open.name();
public void setStatus(TaskStatus status) { this.status = status.name(); }
public String getStatus() { return this.status; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Task(String _name) { this.name = _name; }
public Task() {}
}
TaskStatus.java
public enum TaskStatus {
Open("Open"),
InProgress("In Progress"),
Complete("Complete");
String displayName;
TaskStatus(String displayName) {
this.displayName = displayName;
}
}
MainActivity.java
import io.realm.OrderedCollectionChangeSet;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import io.realm.OrderedRealmCollectionChangeListener;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmResults;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import com.mongodb.realm.examples.model.java.Task;
import com.mongodb.realm.examples.model.java.TaskStatus;
public class MainActivity extends AppCompatActivity {
Realm uiThreadRealm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Realm.init(this); // context, usually an Activity or Application
String realmName = "My Project";
RealmConfiguration config = new RealmConfiguration.Builder().name(realmName).build();
uiThreadRealm = Realm.getInstance(config);
addChangeListenerToRealm(uiThreadRealm);
FutureTask<String> Task = new FutureTask(new BackgroundQuickStart(), "test");
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(Task);
}
private void addChangeListenerToRealm(Realm realm) {
// all Tasks in the realm
RealmResults<Task> Tasks = uiThreadRealm.where(Task.class).findAllAsync();
Tasks.addChangeListener(new OrderedRealmCollectionChangeListener<RealmResults<Task>>() {
@Override
public void onChange(RealmResults<Task> collection, OrderedCollectionChangeSet changeSet) {
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
OrderedCollectionChangeSet.Range[] deletions = changeSet.getDeletionRanges();
for (OrderedCollectionChangeSet.Range range : deletions) {
Log.v("QUICKSTART", "Deleted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1));
}
OrderedCollectionChangeSet.Range[] insertions = changeSet.getInsertionRanges();
for (OrderedCollectionChangeSet.Range range : insertions) {
Log.v("QUICKSTART", "Inserted range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
OrderedCollectionChangeSet.Range[] modifications = changeSet.getChangeRanges();
for (OrderedCollectionChangeSet.Range range : modifications) {
Log.v("QUICKSTART", "Updated range: " + range.startIndex + " to " + (range.startIndex + range.length - 1)); }
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// the ui thread realm uses asynchronous transactions, so we can only safely close the realm
// when the activity ends and we can safely assume that those transactions have completed
uiThreadRealm.close();
}
public class BackgroundQuickStart implements Runnable {
@Override
public void run() {
String realmName = "My Project";
RealmConfiguration config = new RealmConfiguration.Builder().name(realmName).build();
Realm backgroundThreadRealm = Realm.getInstance(config);
Task Task = new Task("New Task");
backgroundThreadRealm.executeTransaction (transactionRealm -> {
transactionRealm.insert(Task);
});
// all Tasks in the realm
RealmResults<Task> Tasks = backgroundThreadRealm.where(Task.class).findAll();
// you can also filter a collection
RealmResults<Task> TasksThatBeginWithN = Tasks.where().beginsWith("name", "N").findAll();
RealmResults<Task> openTasks = Tasks.where().equalTo("status", TaskStatus.Open.name()).findAll();
Task otherTask = Tasks.get(0);
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerOtherTask = transactionRealm.where(Task.class).equalTo("_id", otherTask.getName()).findFirst();
innerOtherTask.setStatus(TaskStatus.Complete);
});
Task yetAnotherTask = Tasks.get(0);
String yetAnotherTaskName = yetAnotherTask.getName();
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction( transactionRealm -> {
Task innerYetAnotherTask = transactionRealm.where(Task.class).equalTo("_id", yetAnotherTaskName).findFirst();
innerYetAnotherTask.deleteFromRealm();
});
// because this background thread uses synchronous realm transactions, at this point all
// transactions have completed and we can safely close the realm
backgroundThreadRealm.close();
}
}
}
MainActivity.kt
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.util.Log
import io.realm.*
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required
import io.realm.kotlin.where
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.FutureTask
class MainActivity : AppCompatActivity() {
lateinit var uiThreadRealm: Realm
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Realm.init(this) // context, usually an Activity or Application
val realmName: String = "My Project"
val config = RealmConfiguration.Builder()
.name(realmName)
.build()
uiThreadRealm = Realm.getInstance(config)
addChangeListenerToRealm(uiThreadRealm)
val task : FutureTask<String> = FutureTask(BackgroundQuickStart(), "test")
val executorService: ExecutorService = Executors.newFixedThreadPool(2)
executorService.execute(task)
}
fun addChangeListenerToRealm(realm : Realm) {
// all tasks in the realm
val tasks : RealmResults<Task> = realm.where<Task>().findAllAsync()
tasks.addChangeListener(OrderedRealmCollectionChangeListener<RealmResults<Task>> { collection, changeSet ->
// process deletions in reverse order if maintaining parallel data structures so indices don't change as you iterate
val deletions = changeSet.deletionRanges
for (i in deletions.indices.reversed()) {
val range = deletions[i]
Log.v("QUICKSTART", "Deleted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val insertions = changeSet.insertionRanges
for (range in insertions) {
Log.v("QUICKSTART", "Inserted range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
val modifications = changeSet.changeRanges
for (range in modifications) {
Log.v("QUICKSTART", "Updated range: ${range.startIndex} to ${range.startIndex + range.length - 1}")
}
})
}
override fun onDestroy() {
super.onDestroy()
// the ui thread realm uses asynchronous transactions, so we can only safely close the realm
// when the activity ends and we can safely assume that those transactions have completed
uiThreadRealm.close()
}
class BackgroundQuickStart : Runnable {
override fun run() {
val realmName: String = "My Project"
val config = RealmConfiguration.Builder().name(realmName).build()
val backgroundThreadRealm : Realm = Realm.getInstance(config)
val task : Task = Task()
task.name = "New Task"
backgroundThreadRealm.executeTransaction { transactionRealm ->
transactionRealm.insert(task)
}
// all tasks in the realm
val tasks : RealmResults<Task> = backgroundThreadRealm.where<Task>().findAll()
// you can also filter a collection
val tasksThatBeginWithN : List<Task> = tasks.where().beginsWith("name", "N").findAll()
val openTasks : List<Task> = tasks.where().equalTo("status", TaskStatus.Open.name).findAll()
val otherTask: Task = tasks[0]!!
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerOtherTask : Task = transactionRealm.where<Task>().equalTo("name", otherTask.name).findFirst()!!
innerOtherTask.status = TaskStatus.Complete.name
}
val yetAnotherTask: Task = tasks.get(0)!!
val yetAnotherTaskName: String = yetAnotherTask.name
// all modifications to a realm must happen inside of a write block
backgroundThreadRealm.executeTransaction { transactionRealm ->
val innerYetAnotherTask : Task = transactionRealm.where<Task>().equalTo("name", yetAnotherTaskName).findFirst()!!
innerYetAnotherTask.deleteFromRealm()
}
// because this background thread uses synchronous realm transactions, at this point all
// transactions have completed and we can safely close the realm
backgroundThreadRealm.close()
}
}
}
enum class TaskStatus(val displayName: String) {
Open("Open"),
InProgress("In Progress"),
Complete("Complete"),
}
open class Task() : RealmObject() {
@PrimaryKey
var name: String = "task"
@Required
var status: String = TaskStatus.Open.name
var statusEnum: TaskStatus
get() {
// because status is actually a String and another client could assign an invalid value,
// default the status to "Open" if the status is unreadable
return try {
TaskStatus.valueOf(status)
} catch (e: IllegalArgumentException) {
TaskStatus.Open
}
}
set(value) { status = value.name }
}

运行上述代码应产生类似以下内容的输出:

Successfully authenticated anonymously.
Updated range: 0 to 1
Deleted range: 0 to 1
Successfully logged out.

来年

欢迎使用 Atlas Device SDK 文档