Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions realm/realm-library/src/main/java/io/realm/BaseRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.realm.internal.Table;
import io.realm.internal.UncheckedRow;
import io.realm.internal.Util;
import io.realm.internal.android.ContextWrapper;
import io.realm.internal.async.RealmThreadPoolExecutor;
import io.realm.log.RealmLog;
import io.realm.internal.ObjectServerFacade;
Expand All @@ -60,8 +61,8 @@ abstract class BaseRealm implements Closeable {
private static final String NOT_IN_TRANSACTION_MESSAGE =
"Changing Realm data can only be done from inside a transaction.";

// Thread pool for all async operations (Query & transaction)
volatile static Context applicationContext;
// Android ContextWrapper. Must be initialized by calling `Realm.init()` before calling any other API's.
volatile static ContextWrapper contextWrapper;

// Thread pool for all async operations (Query & transaction)
static final RealmThreadPoolExecutor asyncTaskExecutor = RealmThreadPoolExecutor.newDefaultExecutor();
Expand Down
11 changes: 6 additions & 5 deletions realm/realm-library/src/main/java/io/realm/Realm.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import android.content.Context;
import android.os.Build;
import android.util.JsonReader;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
Expand Down Expand Up @@ -57,6 +56,7 @@
import io.realm.internal.RealmProxyMediator;
import io.realm.internal.SharedRealm;
import io.realm.internal.Table;
import io.realm.internal.android.ContextWrapper;
import io.realm.internal.async.RealmAsyncTaskImpl;
import io.realm.log.RealmLog;
import rx.Observable;
Expand Down Expand Up @@ -182,15 +182,16 @@ public Observable<Realm> asObservable() {
* @see #getDefaultInstance()
*/
public static synchronized void init(Context context) {
if (BaseRealm.applicationContext == null) {
if (BaseRealm.contextWrapper == null) {
if (context == null) {
throw new IllegalArgumentException("Non-null context required.");
}
RealmCore.loadLibrary(context);
defaultConfiguration = new RealmConfiguration.Builder(context).build();
ContextWrapper wrapper = new ContextWrapper(context);
defaultConfiguration = new RealmConfiguration.Builder(wrapper).build();
ObjectServerFacade.getSyncFacadeIfPossible().init(context);
BaseRealm.applicationContext = context.getApplicationContext();
SharedRealm.initialize(new File(context.getFilesDir(), ".realm.temp"));
BaseRealm.contextWrapper = wrapper;
SharedRealm.initialize(new File(wrapper.getDefaultRealmFileDirectory(), ".realm.temp"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package io.realm;

import android.content.Context;
import android.text.TextUtils;

import java.io.File;
Expand All @@ -32,9 +31,9 @@
import io.realm.annotations.RealmModule;
import io.realm.exceptions.RealmException;
import io.realm.exceptions.RealmFileException;
import io.realm.internal.RealmCore;
import io.realm.internal.RealmProxyMediator;
import io.realm.internal.SharedRealm;
import io.realm.internal.android.ContextWrapper;
import io.realm.internal.modules.CompositeMediator;
import io.realm.internal.modules.FilterableMediator;
import io.realm.rx.RealmObservableFactory;
Expand Down Expand Up @@ -187,7 +186,8 @@ boolean hasAssetFile() {
* @throws IOException if copying the file fails.
*/
InputStream getAssetFile() throws IOException {
return BaseRealm.applicationContext.getAssets().open(assetFilePath);
return BaseRealm.contextWrapper.getAsset(assetFilePath);

}

/**
Expand Down Expand Up @@ -391,20 +391,19 @@ public static class Builder {
* change depending on vendor implementations of Android.
*/
public Builder() {
this(BaseRealm.applicationContext);
this(BaseRealm.contextWrapper);
}

Builder(Context context) {
Builder(ContextWrapper context) {
if (context == null) {
throw new IllegalStateException("Call `Realm.init(Context)` before creating a RealmConfiguration");
}
RealmCore.loadLibrary(context);
initializeBuilder(context);
}

// Setup builder in its initial state
private void initializeBuilder(Context context) {
this.directory = context.getFilesDir();
private void initializeBuilder(ContextWrapper context) {
this.directory = context.getDefaultRealmFileDirectory();
this.fileName = Realm.DEFAULT_REALM_NAME;
this.key = null;
this.schemaVersion = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2016 Realm Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.realm.internal.android;

import android.content.Context;
import android.content.res.AssetManager;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
* This class wraps the Android Context class by extracting all relevant information from the context.
* This means we only need the Context when {@link io.realm.Realm#init(Context)} is called, but we don't
* need to hold onto it.
*
* This should also make Realm play nicer with Instant Run.
*/
public class ContextWrapper {

private final AssetManager assetManager;
private File filesDir;

public ContextWrapper(Context applicationContext) {
assetManager = applicationContext.getAssets();
filesDir = applicationContext.getFilesDir();
}

/**
* Returns the default location for Realm files.
*/
public File getDefaultRealmFileDirectory() {
return filesDir;
}

/**
* Returns an asset specified by a given path.
* On Android this path is assumed to be a path under the {@code assets} folder.
*/
public InputStream getAsset(String assetFilePath) throws IOException {
return assetManager.open(assetFilePath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package io.realm;

import android.content.Context;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URI;
Expand All @@ -34,6 +32,7 @@
import io.realm.exceptions.RealmException;
import io.realm.internal.RealmProxyMediator;
import io.realm.internal.SharedRealm;
import io.realm.internal.android.ContextWrapper;
import io.realm.internal.syncpolicy.AutomaticSyncPolicy;
import io.realm.internal.syncpolicy.SyncPolicy;
import io.realm.rx.RealmObservableFactory;
Expand Down Expand Up @@ -277,14 +276,14 @@ public static final class Builder {
* @see SyncUser#isValid()
*/
public Builder(SyncUser user, String uri) {
this(BaseRealm.applicationContext, user, uri);
this(BaseRealm.contextWrapper, user, uri);
}

Builder(Context context, SyncUser user, String url) {
Builder(ContextWrapper context, SyncUser user, String url) {
if (context == null) {
throw new IllegalStateException("Call `Realm.init(Context)` before creating a SyncConfiguration");
}
this.defaultFolder = new File(context.getFilesDir(), "realm-object-server");
this.defaultFolder = new File(context.getDefaultRealmFileDirectory(), "realm-object-server");
if (Realm.getDefaultModule() != null) {
this.modules.add(Realm.getDefaultModule());
}
Expand Down