如何在onResume中的unbindDrawables之后恢复Fragment?

时间:2014-12-12 08:41:11

标签: android android-fragments

人们使用互联网上的这段代码来释放资源,特别是位图并防止内存泄漏:

public void unbindDrawables(View view) {
    if (view !=null && view.getBackground() != null) {
        view.getBackground().setCallback(null);
    }
    if (view !=null && view instanceof ViewGroup && !(view instanceof AdapterView)) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }

}

人们说他们称之为

onPause

onDestroy

或两者兼而有之。

没有人提到这样一个事实:如果你打开了一个片段,然后从中打开另一个片段,然后再单击一下,第一个片段会留下一个空屏幕?我是唯一一个遇到这个问题的人吗?

只有当我从onPause调用此代码时才会发生这种情况。 如果我从onDestroy调用代码,我没有这个问题,因为当片段不再使用时会调用此方法,但是每次调用onDestroy都不会被调用,并且内存保存效率不高。

我试图将我通常在onCreateView中执行的所有操作移动到onResume,但是当我从第二个片段返回到第一个片段时,我仍然无法重新创建视图层次结构。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    this.inflater = inflater;
    this.container = container;


    getArgumentsAndAssignAccordingValuesToVariables();
    internetUtils = InternetConnectionUtils.getInstance(a);

            return getRootView(inflater, container);
} // End of onCreateView

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    assignLayoutsToJavaObjects(view);
    prepareUserInputEditText();
    initializeEntryLayout();
    setOnClickListeners();
}

@Override
public void onResume() {
    super.onResume(); 
    onCreateView(inflater, container, savedInstanceState); // Just in case. Nothing good happenned
    onViewCreated(getRootView(inflater, container), savedInstanceState); // Just in case. Nothing good happenned
      activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    toggleKeyboard(true);
    setupActionbar();

}

private View getRootView(LayoutInflater inflater, ViewGroup container) {
    if (rootView == null) {
        rootView = inflater.inflate(R.layout.my_layout, container, false);
    }
    return rootView;
}

@Override
public void assignLayoutsToJavaObjects(View rootView) {
    etUserInput = (AutoCompleteTextView) rootView.findViewById(R.id.etTextPageWithUserInput);
    ibGallery = (ImageButton) rootView.findViewById(R.id.gallery);
    rlTextPageWithUserInput = (RelativeLayout) rootView.findViewById(R.id.rlTextPageWithUserInput);
    llEntryPhotos = (LinearLayout) rootView.findViewById(R.id.lEntryPhotos);
}

@Override
public void onPause() {
    super.onPause();
    hideKeyboard();

    stopRunningAsyncTasks();
    cleanMemoryFromBitmapsAndViews();
    rootView = null;
}

@Override
public void onDestroyView() {
    super.onDestroyView();

    //cleanMemoryFromBitmapsAndViews();
    stopRunningAsyncTasks();
}

@Override
public void stopRunningAsyncTasks() {
    if (bitmapWorkAsync != null && activity.asyncTaskStatuses.contains(bitmapWorkAsync.getStatus())) {
        bitmapWorkAsync.cancel(true);
    }
}

private void prepareUserInputEditText() {
    if(etUserInput==null) {
        rootView = inflater.inflate(R.layout.my_layout, container, false);
        assignLayoutsToJavaObjects(rootView);
        rootView.setVisibility(View.VISIBLE); // Added this just in case, no positive change, though
        rootView.invalidate(); // Added this just in case, no positive change, though
    }
    etUserInput.requestFocus(); // Used to get a NPE here, so added the code above
    etUserInput.setCursorVisible(true);
    etUserInput.setHint("Hint");
}

private void initializeEntryLayout() {

    etUserInput.setText("Write here");
    etUserInput.setSelection(etUserInput.getText().length());

        llEntryPhotos.removeAllViews();
        for (int i = 0; i < idsList.size(); i++) {
            LinearLayout photoView = createImageViewWithThumbnail(i);
            if (photoView != null) {
                llPhotos.addView(photoView);
            }

        }

} 

@Override
public void cleanMemoryFromBitmapsAndViews() {
    if (positionsAndBitmaps != null && positionsAndBitmaps.size() > 0) {
        for (Bitmap bitmap : positionsAndBitmaps.values()) {
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
                bitmap = null;
            }
        }
    }
    a.unbindDrawables(rlTextPageWithUserInput);
    a.unbindDrawables(llPhotos);
}

我甚至试过从onResume上调用onCreateView()。

编辑:我想我通过将破坏性代码从onPause / onDestroy移动到onDetach来解决这个问题。我需要更多测试。当片段肯定不再被使用时,onDetach被称为足够晚了,我认为它被称为足够一致。

1 个答案:

答案 0 :(得分:0)

我刚刚将unbindDrawables代码移动到

onDetach()

这种方式几乎总是被调用,最重要的是它会在片段不再使用的时候被调用,所以我们没有尝试恢复和重绘片段的视图的问题