Docs Menu
Docs Home
/ /
SDK de dispositivos Atlas

Inicio rápido - SDK de Java

Tip

Esta guía no utiliza la sincronización del dispositivo

Esta guía puede ayudarte a empezar a usar Realm local del dispositivo. Si tu aplicación necesita comunicarse con una aplicación backend a través de la red mediante funciones como Para sincronizar dispositivos Atlas, funciones de Realm o administración de usuarios, debe seguir la guía de Inicio rápido con sincronización.

Esta página contiene información para integrar rápidamente Realm en tu app. Antes de empezar, asegúrate de tener:

  • Instalé el SDK de Java

Antes de usar Realm en tu aplicación, debes inicializar la biblioteca Realm. Tu aplicación debe inicializar Realm solo una vez cada vez que se ejecuta.

Para inicializar la biblioteca Realm, proporcione un Android context A la Realm.init() función estática. Puede proporcionar una Actividad, Fragmento o Aplicación context para la inicialización sin ninguna diferencia de comportamiento. Puede inicializar la biblioteca Realm en el onCreate() método de una subclase de aplicación. para garantizar que solo inicialice Realm una vez cada vez que se ejecute la aplicación.

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

Tip

Registra tu subclase de aplicación en el manifiesto de Android

Si crea su propia subclase Application, debe agregarla a la AndroidManifest.xml de su aplicación para ejecutar la lógica de aplicación personalizada. Configure la propiedad android.name en la definición de aplicación de su manifiesto para garantizar que Android cree una instancia de su subclase Application antes que cualquier otra clase cuando un usuario inicie su aplicación.

<?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>

El modelo de datos de su aplicación define la estructura de los datos almacenados en Realm. Puede definirlo mediante clases Kotlin o Java en el código de su aplicación con los Modelos de Objetos de Realm.

Para definir el modelo de datos de su aplicación, agregue las siguientes definiciones de clase al código de su aplicación:

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() {}
}
Estado de la tarea.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 }
}

Utilice RealmConfiguration para controlar los detalles del reino que desea abrir, incluido el nombre o la ubicación del reino, si desea permitir lecturas o escrituras sincrónicas en un reino en el hilo de UI y más.

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)

Una vez que haya abierto un reino, puede modificar los objetos dentro de ese reino en un bloque de transacción de escritura.

Importante

Lecturas y escrituras sincrónicas en el hilo de interfaz de usuario

De forma predeterminada, solo se puede leer o escribir en un dominio en el hilo de interfaz de usuario de la aplicación mediante transacciones asíncronas. Es decir, solo se pueden usar Realm métodos cuyo nombre termine con la palabra Async en el hilo principal de la aplicación Android, a menos que se permita explícitamente el uso de métodos síncronos.

Esta restricción existe en beneficio de los usuarios de tu aplicación: realizar operaciones de lectura y escritura en el hilo de la Interfaz de Usuario puede generar interacciones lentas o no respondidas en la Interfaz de Usuario, por lo que generalmente es mejor gestionar estas operaciones de manera asíncrona o en un hilo en segundo plano. Sin embargo, si tu aplicación requiere el uso de lecturas o escrituras de realm síncronas en el hilo de la IU, puedes permitir explícitamente el uso de métodos síncronos con las siguientes opciones 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.")
}
})

Para crear un nuevo Task, cree una instancia de la clase Task y agréguela al reino en un bloque de escritura:

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)
}

Puedes recuperar una colección en vivo de todos los elementos en el Realm:

// 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()

También puedes filtrar esa colección usando un filtro:

// 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()

Para modificar una tarea, actualice sus propiedades en un bloque de transacción de escritura:

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
}

Finalmente, puedes eliminar una tarea llamando al método deleteFromRealm() en un bloque de transacción de escritura:

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()
}

Puede supervisar un reino, una colección o un objeto para detectar cambios adjuntando un personalizado OrderedRealmCollectionChangeListener con el addChangeListener() método:

// 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}")
}
})

Si está ejecutando este proyecto en un proyecto nuevo de Android Studio, puede copiar y pegar este archivo en el MainActivity de su aplicación. Solo recuerde:

  • utiliza una declaración de paquete en la parte superior del archivo para tu propio proyecto

  • Actualice las declaraciones import para Task y TaskStatus si está usando 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() {}
}
Estado de la tarea.java
public enum TaskStatus {
Open("Open"),
InProgress("In Progress"),
Complete("Complete");
String displayName;
TaskStatus(String displayName) {
this.displayName = displayName;
}
}
Actividad principal.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 }
}

Ejecutar el código anterior debería producir un resultado similar al siguiente:

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

Next

Bienvenido a la Docs de Atlas Device SDK

En esta página