从静态创建对象后调用非静态方法,它会产生泄漏内存吗?

时间:2016-11-14 08:32:23

标签: android memory-leaks

我已经学会了不在变量中存储上下文,因为它可能会导致内存泄漏。所以我通过插入weakhashmap超越了上下文。但是我还需要使用AssetManager。

那么,这段代码泄漏内存是否安全?

public class FileUtils {
    private static WeakHashMap<Context, FileUtils> contexts = new WeakHashMap<>();
    private final AssetManager assets;

    private FileUtils(Context context) {
        this.assets = context.getAssets();
    }

    public static FileUtils withContext(Context context) {
        if (contexts.containsKey(context)) {
            return contexts.get(context);
        } else {
            FileUtils downloader = new FileUtils(context);
            contexts.put(context, downloader);
            return downloader;
        }
    }

    public String[] getCodecNamesInArray(ArrayList<File> extract, String folderName) {
        String[] codecsArray = new String[0];

        if (extract == null) {
            try {
                codecsArray = assets.list(folderName);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            codecsArray = new String[extract.size()];
            for (int i = 0; i < extract.size(); i++) {
                codecsArray[i] = extract.get(i).getName();
            }
        }
        return codecsArray;
    }
}

致电活动:

FileUtils.fromContext(this).getCodecNamesInArray(list, folderName);

1 个答案:

答案 0 :(得分:0)

是的,由于您的私人构造函数分配,它仍然会泄漏内存 如果先没有设置上下文,那么资产将保留一个链接。

  1. 你的意思是 withContext()而不是 fromContext ,是不是?

      

    FileUtils.fromContext(this).getCodecNamesInArray(list,folderName);

  2. 函数 getCodecNamesInArray()不会泄漏内存,但 fromContext(this)

  3. 我建议你首先将 getCodecNamesInArray()标记为公共静态,然后将 Context作为参数进行解析。这样就不会泄露

  4. 如果您真的想保留当前的API,请尝试使用

  5.   

    public class FileUtils {
                private static WeakReference<Context> ref;
                private FileUtils(Context context) {
                    ref = new WeakReference<>(context);
                }
    
                public static FileUtils withContext(Context context) {
                    return new FileUtils(context);
                }
    
                public String[] getCodecNamesInArray(ArrayList<File> extract, String folderName) {
                    // TODO: Checking ref.get() return null
    
                    String[] codecsArray = new String[0];
                    if (extract == null) {
                        try {
                            final AssetManager assets = ref.get().getAssets();
                            codecsArray = assets.list(folderName);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    } else {
                        codecsArray = new String[extract.size()];
                        for (int i = 0; i < extract.size(); i++) {
                            codecsArray[i] = extract.get(i).getName();
                        }
                    }
                    return codecsArray;
                }
            }