Realm 열기 및 닫기 - Java SDK
이 페이지의 내용
Android 애플리케이션에서 영역과 상호작용하려면 다음과 같은 상위 수준의 단계를 사용합니다.
열려는 영역에 대한 구성을 만듭니다.
구성을 사용하여 영역을 엽니다.
작업이 완료되면 Realm 을 닫아 리소스를 확보하세요.
기본 Realm
setDefaultConfiguration() 메서드를 사용하여 RealmConfiguration 또는 SyncConfiguration 을 애플리케이션의 기본값으로 저장할 수 있습니다.
RealmConfiguration config = new RealmConfiguration.Builder() .name("default-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .inMemory() .build(); // set this config as the default realm Realm.setDefaultConfiguration(config);
val config = RealmConfiguration.Builder() .name("default-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .inMemory() .build() // set this config as the default realm Realm.setDefaultConfiguration(config)
그런 다음 getDefaultConfiguration()을 사용하여 해당 구성에 액세스하거나 getDefaultInstance()를 사용하여 해당 구성이 있는 영역을 열 수 있습니다.
Realm realm = Realm.getDefaultInstance(); Log.v("EXAMPLE","Successfully opened the default realm at: " + realm.getPath());
val realm = Realm.getDefaultInstance() Log.v("EXAMPLE","Successfully opened the default realm at: ${realm.path}")
로컬 Realm
로컬 영역은 클라이언트 장치에만 데이터를 저장합니다. RealmConfiguration
(으)로 로컬 영역의 설정을 사용자 지정할 수 있습니다.
로컬 Realm 구성
영역에 대한 설정을 구성하려면 영역Configuration.Builder를 사용하여 영역Configuration을 생성합니다. 다음 예시에서는 로컬 영역을 다음과 같이 구성합니다.
파일 이름은 'alternate-realm'
UI 스레드에서 명시적으로 허용되는 동기식 읽기
UI 스레드에서 명시적으로 허용되는 동기식 쓰기
파일 공간 절약을 위한 영역 실행 시 자동 압축
RealmConfiguration config = new RealmConfiguration.Builder() .name("alternate-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .build(); Realm realm = Realm.getInstance(config); Log.v("EXAMPLE", "Successfully opened a realm at: " + realm.getPath());
val config = RealmConfiguration.Builder() .name("alternate-realm") .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .compactOnLaunch() .build() val realm = Realm.getInstance(config) Log.v("EXAMPLE", "Successfully opened a realm at: ${realm.path}")
중요
UI 스레드의 동기식 읽기 및 쓰기
기본적으로 비동기 트랜잭션을 사용하여 애플리케이션의 UI 스레드에서 영역에 읽기 또는 쓰기만 가능합니다. 즉, 동기 메서드의 사용을 명시적으로 허용하지 않는 한 Android 애플리케이션의 기본 스레드에서 이름이 Async
(이)라는 단어로 끝나는 Realm
메서드만 사용할 수 있습니다.
이러한 제한은 애플리케이션 사용자를 위해 존재합니다. 즉, UI 스레드에서 읽기 및 쓰기 작업을 수행하면 UI 상호 작용이 응답하지 않거나 느려질 수 있으므로 일반적으로 이러한 작업을 비동기적으로 처리하거나 배경 스레드에서 처리하는 것이 가장 좋습니다. 하지만 애플리케이션이 UI 스레드에서 동기 영역 읽기 또는 쓰기를 사용해야 하는 경우 다음 SyncConfiguration
옵션을 사용하여 동기 메서드 사용을 명시적으로 허용할 수 있습니다.
SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION) .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build(); Realm.getInstanceAsync(config, new Realm.Callback() { 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.") } })
로컬 Realm 열기
Realm을 열려면 RealmConfiguration.Builder 를 사용하여 RealmConfiguration 을 생성하고 결과 RealmConfiguration
를 getInstance() 또는 getInstanceAsync()에 전달합니다.
RealmConfiguration config = new RealmConfiguration.Builder() .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build(); Realm realm; try { realm = Realm.getInstance(config); Log.v("EXAMPLE", "Successfully opened a realm at: " + realm.getPath()); } catch (RealmFileException ex) { Log.v("EXAMPLE", "Error opening the realm."); Log.v("EXAMPLE", ex.toString()); }
val config = RealmConfiguration.Builder() .allowQueriesOnUiThread(true) .allowWritesOnUiThread(true) .build() var realm: Realm try { realm = Realm.getInstance(config) Log.v("EXAMPLE", "Successfully opened a realm at: ${realm.path}") } catch(ex: RealmFileException) { Log.v("EXAMPLE", "Error opening the realm.") Log.v("EXAMPLE", ex.toString()) }
읽기 전용 Realm
자주 변경되지 않는 공유 데이터가 포함된 준비된 Realm 파일을 앱과 함께 제공하는 것이 유용할 때가 있습니다. Realm을 읽기 전용으로 구성할 때 readOnly() 메서드를 사용할 수 있습니다. 이렇게 하면 실수로 Realm에 쓰는 것을 방지할 수 있으며 쓰기가 발생하면 Realm에서 IllegalStateException
오류가 발생합니다.
경고
읽기 전용 Realm 파일은 쓰기 가능합니다.
읽기 전용 영역은 프로세스 중 읽기 전용으로만 적용됩니다. 영역 파일 자체는 여전히 쓰기 가능합니다.
RealmConfiguration config = new RealmConfiguration.Builder() .assetFile("bundled.realm") .readOnly() .modules(new BundledRealmModule()) .build();
val config = RealmConfiguration.Builder() .assetFile("readonly.realm") .readOnly() .modules(BundledRealmModule()) .build()
인메모리 Realm
파일 에 기록하지 않고 메모리에서 완전히 실행되는 영역 을 만들 수 있습니다. Android 기기에서 메모리가 부족하면 인메모리 영역이 으로 스왑 될 수 있습니다. 임시로 메인 메모리에서 디스크 공간으로 이동합니다. SDK는 다음과 같은 경우 인메모리 영역 에서 생성된 모든 파일을 삭제합니다.
영역이 닫힙니다.
해당 영역에 대한 모든 참고는 범위에서 제외됩니다.
인메모리 영역을 생성하려면 영역을 구성할 때 inMemory ()를 사용하세요.
RealmConfiguration config = new RealmConfiguration.Builder() .inMemory() .name("java.transient.realm") .build(); Realm realm = Realm.getInstance(config);
val config = RealmConfiguration.Builder() .inMemory() .name("kt.transient.realm") .build() val realm = Realm.getInstance(config)
동적 Realm
기존 영역은 RealmObject
하위 클래스 또는 RealmModel
인터페이스를 사용하여 스키마를 정의합니다. DynamicRealm 은 문자열을 사용하여 런타임에 스키마를 정의합니다. 동적 Realm을 열면 기존 Realm과 동일한 구성이 사용되지만 동적 Realm은 구성된 모든 스키마, 마이그레이션 및 스키마 버전을 무시합니다.
동적 영역은 유형 안전성과 성능을 희생하는 대신 유연성을 제공합니다. 따라서 마이그레이션, 수동 클라이언트 재설정, CSV 파일이나 JSON과 같은 문자열 기반 데이터로 작업할 때와 같이 유연성이 필요한 경우에만 동적 영역을 사용하세요.
변경 가능한 스키마가 있는 동적 Realm을 열려면 DynamicRealm을 사용합니다.
RealmConfiguration config = new RealmConfiguration.Builder() .allowWritesOnUiThread(true) .allowQueriesOnUiThread(true) .name("java.dynamic.realm") .build(); DynamicRealm dynamicRealm = DynamicRealm.getInstance(config); // all objects in a DynamicRealm are DynamicRealmObjects AtomicReference<DynamicRealmObject> frog = new AtomicReference<>(); dynamicRealm.executeTransaction(transactionDynamicRealm -> { // add type Frog to the schema with name and age fields dynamicRealm.getSchema() .create("Frog") .addField("name", String.class) .addField("age", int.class); frog.set(transactionDynamicRealm.createObject("Frog")); frog.get().set("name", "Wirt Jr."); frog.get().set("age", 42); }); // access all fields in a DynamicRealm using strings String name = frog.get().getString("name"); int age = frog.get().getInt("age"); // because an underlying schema still exists, // accessing a field that does not exist throws an exception try { frog.get().getString("doesn't exist"); } catch (IllegalArgumentException e) { Log.e("EXAMPLE", "That field doesn't exist."); } // Queries still work normally RealmResults<DynamicRealmObject> frogs = dynamicRealm.where("Frog") .equalTo("name", "Wirt Jr.") .findAll();
val config = RealmConfiguration.Builder() .allowWritesOnUiThread(true) .allowQueriesOnUiThread(true) .name("kt.dynamic.realm") .build() val dynamicRealm = DynamicRealm.getInstance(config) // all objects in a DynamicRealm are DynamicRealmObjects var frog: DynamicRealmObject? = null dynamicRealm.executeTransaction { transactionDynamicRealm: DynamicRealm -> // add type Frog to the schema with name and age fields dynamicRealm.schema .create("Frog") .addField("name", String::class.java) .addField("age", Integer::class.java) frog = transactionDynamicRealm.createObject("Frog") frog?.set("name", "Wirt Jr.") frog?.set("age", 42) } // access all fields in a DynamicRealm using strings val name = frog?.getString("name") val age = frog?.getInt("age") // because an underlying schema still exists, // accessing a field that does not exist throws an exception try { frog?.getString("doesn't exist") } catch (e: IllegalArgumentException) { Log.e("EXAMPLE", "That field doesn't exist.") } // Queries still work normally val frogs = dynamicRealm.where("Frog") .equalTo("name", "Wirt Jr.") .findAll()
Realm 닫기
Realm 인스턴스에서 리소스를 비우려면 close() 메서드를 호출해야 한다는 점을 기억합니다. Realm을 닫지 않으면 OutOfMemoryError
가 발생할 수 있습니다.
realm.close();
realm.close()
Realm 스키마에 포함할 클래스 구성하기
Realm 모듈은 Realm 객체 모델의 모음입니다. Realm이 스키마에 포함해야 하는 클래스를 제어하려면 영역을 열 때 모듈을 하나 또는 여러 개 지정합니다. 모듈을 지정하지 않으면 Realm은 애플리케이션에 정의된 모든 Realm 객체를 포함하는 기본 모듈을 사용합니다.
참고
Realm이 포함된 라이브러리는 모듈을 통해 스키마를 노출하고 사용해야 합니다. 이렇게 하면 라이브러리가 기본 RealmModule
을(를) 생성하지 못하므로 라이브러리를 포함한 모든 앱에서 사용하는 기본 RealmModule
과(와) 충돌하게 됩니다. 라이브러리를 사용하는 앱은 모듈을 통해 라이브러리 클래스에 액세스합니다.
// A 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. public class MyLibraryModule {} // ... // Library projects are therefore required to explicitly set their own module. SyncConfiguration libraryConfig = new SyncConfiguration.Builder(app.currentUser(), LIBRARY_PARTITION) .modules(new MyLibraryModule()) .build(); // Apps can add the library RealmModule to their own schema. SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION) .modules(Realm.getDefaultModule(), new MyLibraryModule()) .build();
// A 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. class MyLibraryModule // ... // Library projects are therefore required to explicitly set their own module. val libraryConfig = SyncConfiguration.Builder(app.currentUser(), LIBRARY_PARTITION) .modules(MyLibraryModule()) .build() // Apps can add the library RealmModule to their own schema. val config = SyncConfiguration.Builder(app.currentUser(), PARTITION) .modules(Realm.getDefaultModule(), MyLibraryModule()) .build()