内存问题 - 碎片

Mar*_*los 4 android memory-leaks memory-management android-fragments

我最近重构了一个应用程序,并替换了一个FrameFayip,用于我在Fragments之间交换的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();
    }
Run Code Online (Sandbox Code Playgroud)

我创建了一个新片段并替换旧片段.从屏幕上删除的那些被调用onDestroy,但是我在屏幕上加载的位图消耗的内存不会被删除,因此应用程序在片段之间进行一些交换后崩溃.

我还尝试删除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;
}
Run Code Online (Sandbox Code Playgroud)

但记忆力不断增长.

谁知道任何解决方案?也许重用片段?有效地摧毁它?我在听.

dsk*_*ner 6

我忘记了我最初从这个代码中提取的stackoverflow问题,但是一个似乎运行良好的方法是覆盖onAttachFragmentFragmentActivity,然后将a存储WeakReference到传入的每个片段.然后,不使用FragmentTransaction的replace方法,而是回收所有碎片(与案件相关).

以下是FragmentActivity上的其他成员和方法的示例,它通过以下方式创建默认片段onCreate并响应更改onNewIntent:

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();
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您监控堆,您应该注意到它的大小并没有变大.当您拥有包含位图的嵌套片段时,这种解决方案大多会发挥作用,这些位图由于某种原因似乎无法正确回收.我喜欢更优雅的解决方案,但这个有效.