4

我最近重构了一个应用程序,并替换了一个ViewFlipper,用于在片段之间交换的FrameLayout。内存问题 - 片段

每次用户请求的意见之一:

public void showLibraryOf(long publisherId) { 
     library = new DownloadLibraryFragment(id, viewFactory()); 

     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.container, library); 
     ft.commit(); 

     library.setAdapterObserver(this); 
    } 

    public void showMyLibraryOf(long publisherId) { 
     myLibrary = new MyLibraryFragment(id, viewFactory()); 

     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.container, myLibrary); 
     ft.commit(); 
    } 

    public void showHelp() { 
     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.container, new HelpFragment()); 
     ft.commit(); 
    } 

我创建一个新片段,并更换旧的。那些被从屏幕上移除的getDestroy被调用,但是我在屏幕上加载的位图消耗的内存没有被移除,所以应用程序在片段之间进行一些交换后崩溃。

我也试过在的onDestroy

@Override 
public void onDestroyView() { 
    destroy(); 
    super.onDestroyView(); 
    adapter.clear(); 
    adapter.clearObservers(); 
    adapter.notifyDataSetChanged(); 

    view.setAdapter(new ArrayAdapter<Journal>(getActivity(), 0)); 

    adapter = null; 
    view = null; 
} 

删除引用但记忆保持增长。

任何人都知道任何解决方案?也许重用碎片?有效地摧毁它?我在听。

+0

看来,别人也有类似的问题在这里:http://stackoverflow.com/questions/9257952/memory-issues-in-fragments-showing-images这有帮助吗? – scriptocalypse 2012-04-02 21:47:13

+0

[Bitmap#recycle()](http://developer.android.com/reference/android/graphics/Bitmap.html#recycle%28%29)如果可以或[System.gc()](http:/ /developer.android.com/reference/java/lang/System.html#gc%28%29)。只需清除适配器不会立即回收位图( – zapl 2012-04-02 22:49:01

+0

scriptocalypse),这是类似的,但是通过寻呼机,所以生命周期由FragmentAdapter管理。根本没有帮助我。 – 2012-04-04 20:50:25

回答

6

我忘了StackOverflow上的问题,我最初拉着从这个代码,但这似乎运作良好一种方法是重写FragmentActivityonAttachFragment,然后存储WeakReference在传递的每个片段,然后,而不是使用替代FragmentTransaction的方法,你回收所有的片段(与案例相关)。

这里有在onCreate创建默认片段和响应通过onNewIntent到变化的FragmentActivity其他成员和方法的一个例子:

private List<WeakReference<Fragment>> mFragments = 
    new ArrayList<WeakReference<Fragment>>(); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
    ft.add(R.id.fragment_container, MyFragment.newInstance("default")); 
    ft.commit(); 
} 

@Override 
protected void onNewIntent(Intent intent) { 
    setIntent(intent); 
    String section = intent.getStringExtra("section"); 
    recycleFragments(); 
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
    ft.add(R.id.fragment_container, MyFragment.newInstance(section)); 
    ft.commit(); 
} 

@Override 
public void onAttachFragment(Fragment fragment) { 
    mFragments.add(new WeakReference<Fragment>(fragment)); 
} 

private void recycleFragments() { 
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 

    for (WeakReference<Fragment> ref : mFragments) { 
     Fragment fragment = ref.get(); 
     if (fragment != null) { 
      ft.remove(fragment); 
     } 
    } 

    ft.commit(); 
} 

现在,如果你监视堆,你应该注意到这不是吹起来在尺寸方面。这种解决方案通常在嵌套包含位图的片段时发挥作用,这些位图由于某些原因似乎不能正确回收。我想要一个更优雅的解决方案,但这个工作。