人们使用互联网上的这段代码来释放资源,特别是位图并防止内存泄漏:
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被称为足够晚了,我认为它被称为足够一致。答案 0 :(得分:0)
我刚刚将unbindDrawables代码移动到
onDetach()
这种方式几乎总是被调用,最重要的是它会在片段不再使用的时候被调用,所以我们没有尝试恢复和重绘片段的视图的问题