react native内存优化

来源:互联网 发布:网络未注册是什么意思 编辑:程序博客网 时间:2024/04/28 20:21

react native在加载大量图片时小伙伴们会发现,内存一路飙升150M-200M那都不是问题,今天就来优化一下内存,降至40M左右。

1:实现一个module 

import android.app.ActivityManager;import android.content.Context;import android.os.Build;import android.support.annotation.Nullable;import com.facebook.cache.common.CacheKey;import com.facebook.cache.disk.DiskCacheConfig;import com.facebook.common.internal.AndroidPredicates;import com.facebook.common.internal.Supplier;import com.facebook.common.soloader.SoLoaderShim;import com.facebook.common.util.ByteConstants;import com.facebook.drawee.backends.pipeline.Fresco;import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory;import com.facebook.imagepipeline.cache.MemoryCacheParams;import com.facebook.imagepipeline.core.ImagePipelineConfig;import com.facebook.imagepipeline.core.ImagePipelineFactory;import com.facebook.imagepipeline.listener.RequestListener;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.modules.common.ModuleDataCleaner;import com.facebook.react.modules.fresco.SystraceRequestListener;import com.facebook.react.modules.network.OkHttpClientProvider;import com.facebook.soloader.SoLoader;import java.util.HashSet;import okhttp3.OkHttpClient;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, getDefaultConfig(reactContext, listener, null));    }    public MyFrescoModule(            ReactApplicationContext reactContext,            RequestListener listener,            DiskCacheConfig diskCacheConfig) {        this(reactContext, getDefaultConfig(reactContext, listener, 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,0,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);        }    }}

因为react native在android中使用fresco来加载图片,所以我们自定义自己的fresco来覆盖掉默认的。

2:继承MainReactPackage 实现getNativeMoudules方法 代码如下:

/** * Created by xq on 16/11/11. */public class RNMainReactPackage extends MainReactPackage {    @Override    public List<ModuleSpec> getNativeModules(ReactApplicationContext context) {        return Arrays.asList(                new ModuleSpec(AppStateModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new AppStateModule(context);                    }                }),                new ModuleSpec(AsyncStorageModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new AsyncStorageModule(context);                    }                }),                new ModuleSpec(CameraRollManager.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new CameraRollManager(context);                    }                }),                new ModuleSpec(ClipboardModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new ClipboardModule(context);                    }                }),                new ModuleSpec(DatePickerDialogModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new DatePickerDialogModule(context);                    }                }),                new ModuleSpec(DialogModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new DialogModule(context);                    }                }),                new ModuleSpec(MyFrescoModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new MyFrescoModule(context);                    }                }),                new ModuleSpec(I18nManagerModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new I18nManagerModule(context);                    }                }),                new ModuleSpec(ImageEditingManager.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new ImageEditingManager(context);                    }                }),                new ModuleSpec(ImageLoaderModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new ImageLoaderModule(context);                    }                }),                new ModuleSpec(ImageStoreManager.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new ImageStoreManager(context);                    }                }),                new ModuleSpec(IntentModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new IntentModule(context);                    }                }),                new ModuleSpec(LocationModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new LocationModule(context);                    }                }),                new ModuleSpec(NativeAnimatedModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new NativeAnimatedModule(context);                    }                }),                new ModuleSpec(NetworkingModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new NetworkingModule(context);                    }                }),                new ModuleSpec(NetInfoModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new NetInfoModule(context);                    }                }),                new ModuleSpec(PermissionsModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new PermissionsModule(context);                    }                }),                new ModuleSpec(ShareModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new ShareModule(context);                    }                }),                new ModuleSpec(StatusBarModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new StatusBarModule(context);                    }                }),                new ModuleSpec(TimePickerDialogModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new TimePickerDialogModule(context);                    }                }),                new ModuleSpec(ToastModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new ToastModule(context);                    }                }),                new ModuleSpec(VibrationModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new VibrationModule(context);                    }                }),                new ModuleSpec(WebSocketModule.class, new Provider<NativeModule>() {                    @Override                    public NativeModule get() {                        return new WebSocketModule(context);                    }                }));    }}

3:在mainapplication的getpackages方法里面替换MainReactPackage

@Overrideprotected List<ReactPackage> getPackages() {  return Arrays.<ReactPackage>asList(          new RNMainReactPackage(),  );}

4:运行ok. 亲测效果显著。

截图:





0 0
原创粉丝点击