2016-11-14 64 views
0

我學會了不要在變量中存儲上下文,因爲它可能會導致內存泄漏。所以我通過插入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); 

回答

0

是的,它仍然泄漏內存由於您的私人構造函數分配。
如果上下文尚未設置,則資產將保留指向它的鏈接。

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

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

  2. 功能getCodecNamesInArray()不會泄漏的內存,但fromContext(本)

  3. 我建議你先標記getCodecNamesInArray()公共靜態然後解析上下文作爲論據。這樣,它不會泄露

  4. 如果你真的想保持現有的API,試試這個

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; 
      } 
     }