react-native内存优化--图片内存

react-native在android中使用fresco来加载图片。说到fresco很多人都会为之欢呼,总比各种轮子内存调优的好。不过在react-native中在它的使用fresco还是稍显随意,如果一个页面是典型的图列表,运行一段时间用dumpsys meminfo命令观察您的程序内存会出现令您惊讶的内存暴增。
为了使得图片内存好看点,我们来修改以下react-native的FrescoModule模块。

public class MyFrescoModule extends ReactContextBaseJavaModule implements
        ModuleDataCleaner.Cleanable {

    private @Nullable
    ImagePipelineConfig mConfig;

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

    public MyFrescoModule(ReactApplicationContext reactContext,RequestListener listener) {
        this(reactContext,listener,null));
    }

    public MyFrescoModule(
            ReactApplicationContext reactContext,RequestListener listener,diskCacheConfig diskCacheConfig) {
        this(reactContext,diskCacheConfig));
    }

    public MyFrescoModule(ReactApplicationContext reactContext,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 MyFrescoModule.FrescoHandler());

        Context context = getReactApplicationContext().getApplicationContext();
        Fresco.initialize(context,mConfig);
        mConfig = null;
    }

    @Override
    public String getName() {
        return "FrescoModule";
    }

    @Override
    public void clearSensitiveData() {
        // Clear image cache.
        ImagePipelineFactory imagePipelineFactory = Fresco.getimagePipelineFactory();
        imagePipelineFactory.getBitmapMemoryCache().removeAll(AndroidPredicates.<CacheKey>True());
        imagePipelineFactory.getEncodedMemoryCache().removeAll(AndroidPredicates.<CacheKey>True());
    }

    private static ImagePipelineConfig getDefaultConfig(
            Context context,@Nullable RequestListener listener,@Nullable diskCacheConfig diskCacheConfig) {
        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);
        }

        final int maxCacheSize= getMaxCacheSize(context);
        builder.setBitmapMemoryCacheParamssupplier(new supplier<MemoryCacheParams>() {
            @Override
            public MemoryCacheParams get() {
                return new MemoryCacheParams(maxCacheSize,100,Integer.MAX_VALUE,Integer.MAX_VALUE);
            }
        });

        return builder.build();
    }
    private static int getMaxCacheSize(Context context) {
        final ActivityManager activityManager=(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        final int maxMemory =  Math.min(activityManager.getMemoryClass() * ByteConstants.MB,Integer.MAX_VALUE);
        if (maxMemory < 32 * ByteConstants.MB) {
            return 4 * ByteConstants.MB;
        } else if (maxMemory < 64 * ByteConstants.MB) {
            return 6 * ByteConstants.MB;
        } else {
            // We don't want to use more ashmem on Gingerbread for Now,since it doesn't respond well to
            // native memory pressure (doesn't throw exceptions,crashes app,crashes phone)
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
                return 8 * ByteConstants.MB;
            } else {
                return maxMemory / 4;
            }
        }
    }
    private static class FrescoHandler implements SoLoaderShim.Handler {
        @Override
        public void loadLibrary(String libraryName) {
            SoLoader.loadLibrary(libraryName);
        }
    }
}

这里我们重新实现了MyFrescoModule,之所以不继承FrescoModule是因为FrescoModule里的getDefaultConfig函数是static的。

下一步继承MainReactPackage 替换掉MainReactPackage ,overridecreateNativeModules方法将FrescoModule替换成MyFrescoModule。

最后run起来再看看您的应用内存是怎样的。祝您好运!

相关文章

一、前言 在组件方面react和Vue一样的,核心思想玩的就是组件...
前言: 前段时间学习完react后,刚好就接到公司一个react项目...
前言: 最近收到组长通知我们项目组后面新开的项目准备统一技...
react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...