内存泄漏,singleInstance

时间:2012-06-25 13:42:17

标签: android android-layout

我有几个活动,我在this lib的帮助下显示图像。问题是应用程序内存不足。我尝试了gc.clean(),null引用,在imageloader对象上调用clear但是徒劳无功。

在MAT中,我发现我有多个具有相同活动的对象,如果我没有弄错的话,它是默认行为。我使用singleInstance来抑制多个实例,它帮助了内存泄漏。

现在,由于singleInstance,我遇到了导航问题。你认为我应该继续使用singleInstance还是尝试修复多个实例的内存泄漏?

这是ImageView gc根检查: enter image description here

UPD:

 Bitmap bitmap=null;
        URL imageUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        conn.setInstanceFollowRedirects(true);
        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;

    ImageView imageView = (ImageView) convertView;
    if(convertView == null){
        imageView = new ImageView(_currentActivity);
    }

UPD2(导航策略):

我有一个带有按钮的常量标题,用于启动主页活动(带有图库)和个人资料活动;其次,还有一个子标题,它还包含3个按钮,指向另外3个列表视图活动(包括图像视图+标签)。

这些标题,子标题元素可用于应用程序中的每个活动;链接按钮除了:

之外什么都不做
startActivity(new Intent(getActivity(), MainActivity.class));

Intent activityIntent = new Intent(getActivity(), SomeActivityWithListViewInside.class);
// passing some data like list id
activityIntent.putExtra("list_id", listId);
startActivity(activityIntent);

因此,那些活动实例是由那些startActivity调用引起的 - 你认为我应该使用singleTop或任何其他的intent参数来避免这个问题吗?

3 个答案:

答案 0 :(得分:3)

我强烈建议不要使用活动的怪异标志。我也总是遇到使用android API的导航问题(并且仍然有片段)。

相反,我建议你解决内存问题。

您应该关注内存泄漏 this video ,并阅读 this about bitmaps

简而言之,这里有一些提示:

  1. 尽量避免使用静态引用,尤其是当它们引用上下文时。

  2. 尽量避免引用上下文。

  3. 如果必须引用上下文,请考虑使用ApplicationContext。

  4. 记得在关闭活动时关闭线程和对话框(如果需要)。尝试在不再需要服务时关闭服务。

  5. 更喜欢静态内部类而不是非静态内部类(因为那些引用了包含类)。

  6. 请记住,匿名类也引用了包含类。

  7. 小心你的缓存。尽量避免缓存包含对上下文的引用的类,例如视图和drawable。

  8. 如果可能,请尝试使用softReference和/或weakReference来引用引用上下文的“危险”对象。

  9. 在Android API 10及更低版本的
  10. ,请记住回收您的位图。他们通常会留下很多记忆。

  11. 如果某个活动需要太多内存而你从另一个活动转到另一个活动,请考虑完成并在需要时重新创建它而不是回到旧实例。

  12. 如果您使用任何第三方库或使用本机代码(例如使用NDK),请不要忘记在不需要时释放其内存。达尔维克对你没什么帮助。

答案 1 :(得分:1)

您不应该使用singleInstance launchMode。您需要使用标准和/或singleTop launchMode使导航正常工作。如果您发现自己有多个活动实例,但是没想到,那么导航中出现了问题。拥有多个活动实例会保留所有视图和图像,这可能是造成内存不足问题的原因。

使用您期望的导航更新您的帖子以及您如何管理它,也许我们可以帮助您解决此问题。

编辑:回应海报的UPD:

我不知道你在哪里设置_currentActivity,但这可能是你的问题。在适配器内创建视图时,应始终使用适配器的上下文(在创建时设置)。所以试试这个:

ImageView imageView = (ImageView) convertView;
if(convertView == null){
    imageView = new ImageView(getContext());
}

编辑:回应海报的UPD2:

您需要检查导航以确保当用户选择标题或子标题中的某个按钮时,您在活动堆栈中没有多个活动实例(如果这不是您想要的) )。如果您的活动使用大量图像空间(位图等),那么您希望确保没有多个实例。您可以重新考虑导航,也可以使用singleTop,clearTop,reorderToFront等组合,这样您就不会继续创建活动实例,只需在活动堆栈中重新排列它们即可获得所需的导航行为。

答案 2 :(得分:0)

在创建视图时将活动作为上下文传递并不好:这可以防止活动被“释放”。此外,您可能希望将位图缩小到您真正需要的大小。