加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 08:24:13 所属栏目:百科 来源:网络整理
导读:react-native在android中使用fresco来加载图片。说到fresco很多人都会为之欢呼,总比各种轮子内存调优的好。不过在react-native中在它的使用fresco还是稍显随意,如果一个页面是典型的图列表,运行一段时间用dumpsys meminfo命令观察您的程序内存会出现令您

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起来再看看您的应用内存是怎样的。祝您好运!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读