Skip to content

Commit

Permalink
Only initialize FrescoModule once
Browse files Browse the repository at this point in the history
Summary:
Fresco should only be initialized once. Re-initializing causes a few problems (#8677) and we don't need to do it.
If a Fresco configuration needs to change, you can just restart the application or add delegates for parts that can change and manually update them instead.

Reviewed By: astreet

Differential Revision: D3790908

fbshipit-source-id: 9df4c3be15ca49433120abd7ba1a4f5ae2a3f1c1
  • Loading branch information
oprisnik authored and Facebook Github Bot 4 committed Aug 31, 2016
1 parent 82dba51 commit c0de1a7
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 42 deletions.
Expand Up @@ -5,6 +5,7 @@ android_library(
srcs = glob(['**/*.java']),
deps = [
react_native_dep('java/com/facebook/systrace:systrace'),
react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'),
react_native_dep('libraries/fresco/fresco-react-native:fbcore'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-drawee'),
react_native_dep('libraries/fresco/fresco-react-native:fresco-react-native'),
Expand All @@ -16,6 +17,7 @@ android_library(
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_dep('third-party/java/okhttp:okhttp3'),
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/modules/common:common'),
react_native_target('java/com/facebook/react/modules/network:network'),
],
Expand Down
Expand Up @@ -14,20 +14,19 @@
import android.content.Context;
import android.support.annotation.Nullable;

import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.soloader.SoLoaderShim;
import com.facebook.common.logging.FLog;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.listener.RequestListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.modules.common.ModuleDataCleaner;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.soloader.SoLoader;

import okhttp3.OkHttpClient;

/**
* Module to initialize the Fresco library.
*
Expand All @@ -38,35 +37,52 @@ public class FrescoModule extends ReactContextBaseJavaModule implements

private @Nullable ImagePipelineConfig mConfig;

public FrescoModule(ReactApplicationContext reactContext) {
this(reactContext, getDefaultConfig(reactContext, null, null));
}

public FrescoModule(ReactApplicationContext reactContext, RequestListener listener) {
this(reactContext, getDefaultConfig(reactContext, listener, null));
}
private static boolean sHasBeenInitialized = false;

public FrescoModule(
ReactApplicationContext reactContext,
RequestListener listener,
DiskCacheConfig diskCacheConfig) {
this(reactContext, getDefaultConfig(reactContext, listener, diskCacheConfig));
/**
* Create a new Fresco module with a default configuration (or the previously given
* configuration via {@link #FrescoModule(ReactApplicationContext, ImagePipelineConfig)}.
*
* @param reactContext the context to use
*/
public FrescoModule(ReactApplicationContext reactContext) {
this(reactContext, null);
}

public FrescoModule(ReactApplicationContext reactContext, ImagePipelineConfig config) {
/**
* Create a new Fresco module with a given ImagePipelineConfig.
* This should only be called when the module has not been initialized yet.
* You can use {@link #hasBeenInitialized()} to check this and call
* {@link #FrescoModule(ReactApplicationContext)} if it is already initialized.
* Otherwise, the given Fresco configuration will be ignored.
*
* @param reactContext the context to use
* @param config the Fresco configuration, which will only be used for the first initialization
*/
public FrescoModule(ReactApplicationContext reactContext, @Nullable ImagePipelineConfig config) {
super(reactContext);
mConfig = config;
}

@Override
public void initialize() {
super.initialize();
// Make sure the SoLoaderShim is configured to use our loader for native libraries.
// This code can be removed if using Fresco from Maven rather than from source
SoLoaderShim.setHandler(new FrescoHandler());

Context context = getReactApplicationContext().getApplicationContext();
Fresco.initialize(context, mConfig);
if (!hasBeenInitialized()) {
// Make sure the SoLoaderShim is configured to use our loader for native libraries.
// This code can be removed if using Fresco from Maven rather than from source
SoLoaderShim.setHandler(new FrescoHandler());
if (mConfig == null) {
mConfig = getDefaultConfig(getReactApplicationContext());
}
Context context = getReactApplicationContext().getApplicationContext();
Fresco.initialize(context, mConfig);
sHasBeenInitialized = true;
} else if (mConfig != null) {
FLog.w(
ReactConstants.TAG,
"Fresco has already been initialized with a different config. "
+ "The new Fresco configuration will be ignored!");
}
mConfig = null;
}

Expand All @@ -81,29 +97,26 @@ public void clearSensitiveData() {
Fresco.getImagePipeline().clearCaches();
}

private static ImagePipelineConfig getDefaultConfig(
Context context,
@Nullable RequestListener listener,
@Nullable DiskCacheConfig diskCacheConfig) {
/**
* Check whether the FrescoModule has already been initialized. If this is the case,
* Calls to {@link #FrescoModule(ReactApplicationContext, ImagePipelineConfig)} will
* ignore the given configuration.
*
* @return true if this module has already been initialized
*/
public static boolean hasBeenInitialized() {
return sHasBeenInitialized;
}

private static ImagePipelineConfig getDefaultConfig(Context context) {
HashSet<RequestListener> requestListeners = new HashSet<>();
requestListeners.add(new SystraceRequestListener());
if (listener != null) {
requestListeners.add(listener);
}

OkHttpClient okHttpClient = OkHttpClientProvider.getOkHttpClient();
ImagePipelineConfig.Builder builder =
OkHttpImagePipelineConfigFactory.newBuilder(context.getApplicationContext(), okHttpClient);

builder
.setDownsampleEnabled(false)
.setRequestListeners(requestListeners);

if (diskCacheConfig != null) {
builder.setMainDiskCacheConfig(diskCacheConfig);
}

return builder.build();
return OkHttpImagePipelineConfigFactory
.newBuilder(context.getApplicationContext(), OkHttpClientProvider.getOkHttpClient())
.setDownsampleEnabled(false)
.setRequestListeners(requestListeners)
.build();
}

private static class FrescoHandler implements SoLoaderShim.Handler {
Expand Down

0 comments on commit c0de1a7

Please sign in to comment.