/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.react.modules.fresco; import java.util.HashSet; import android.content.Context; import android.support.annotation.Nullable; 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.module.annotations.ReactModule; 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. * * <p>Does not expose any methods to JavaScript code. For initialization and cleanup only. */ @ReactModule(name = "FrescoModule") public class FrescoModule extends ReactContextBaseJavaModule implements ModuleDataCleaner.Cleanable { private @Nullable ImagePipelineConfig mConfig; private static boolean sHasBeenInitialized = false; /** * 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); } /** * 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(); 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; } @Override public String getName() { return "FrescoModule"; } @Override public void clearSensitiveData() { // Clear image cache. Fresco.getImagePipeline().clearCaches(); } /** * 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) { return getDefaultConfigBuilder(context).build(); } /** * Get the default Fresco configuration builder. * Allows adding of configuration options in addition to the default values. * * @return {@link ImagePipelineConfig.Builder} that has been initialized with default values */ public static ImagePipelineConfig.Builder getDefaultConfigBuilder(Context context) { HashSet<RequestListener> requestListeners = new HashSet<>(); requestListeners.add(new SystraceRequestListener()); OkHttpClient okHttpClient = OkHttpClientProvider.getOkHttpClient(); return OkHttpImagePipelineConfigFactory .newBuilder(context.getApplicationContext(), okHttpClient) .setNetworkFetcher(new ReactOkHttpNetworkFetcher(okHttpClient)) .setDownsampleEnabled(false) .setRequestListeners(requestListeners); } private static class FrescoHandler implements SoLoaderShim.Handler { @Override public void loadLibrary(String libraryName) { SoLoader.loadLibrary(libraryName); } } }