我正在构建一个包含大量片段的应用程序,但我有一些内存问题。
第一个似乎在我的viewpager中。我正在使用一个fragmentStatePagerAdapter,因为它中可能有很多片段(因此,如果我是正确的话,只应在内存中保留少量片段)。 其中有一个滚动视图,我在每个片段中滚动一下进行测试。我想如果我在左边的5个片段中我会稍微晃动一下然后我回到原来的片段,卷轴应该重置,因为它们不应该保留在内存中,但它是。
以下是我的viewpager的代码:
public class MonoArticlePagerFragment extends Fragment{
private static final String IS_NEW_FRAG = "IS_NEW_FRAG";
private static final String POSITION = "POSITION";
private ViewPager mPager;
private ArticlePagerAdapter mPagerAdapter;
private boolean mIsNewFragment;
private int mPosition;
public static MonoArticlePagerFragment newInstance(boolean isNewFragment, int position) {
Bundle args = new Bundle();
args.putBoolean(IS_NEW_FRAG, isNewFragment);
args.putInt(POSITION, position);
MonoArticlePagerFragment fragment = new MonoArticlePagerFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mIsNewFragment = args.getBoolean(IS_NEW_FRAG);
mPosition = args.getInt(POSITION);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = View.inflate(getActivity(), R.layout.fragment_current_articles_pager,null);
mPager = (ViewPager) rootView.findViewById(R.id.pager);
mPagerAdapter = new ArticlePagerAdapter(getActivity().getSupportFragmentManager(), CurrentArticlesFragment.sListArticles);
mPager.setAdapter(mPagerAdapter);
// mPager.setOffscreenPageLimit(1);
if (!mIsNewFragment) {
mPager.setCurrentItem(mPosition);
} else {
mPager.setCurrentItem(CurrentArticlesFragment.sListArticles.size() - 1);
}
return rootView;
}
}
MonoArticleFragment类:
public class MonoArticleFragment extends Fragment {
private static final String LOG_TAG = "MonoArticleFragment";
private View mPhotos;
private View mGeneral;
private View mSourcing;
private View mNavision;
private View mStatistiques;
private View mDescriptions;
private ScrollView mScrollView;
public static MonoArticleFragment newInstance() {
Bundle args = new Bundle();
MonoArticleFragment fragment = new MonoArticleFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_current_articles_mono, container,false);
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.mono_article_tab_btn_statistiques) {
mScrollView.smoothScrollTo(0,mStatistiques.getTop());
} else if (id == R.id.mono_article_tab_btn_sourcing) {
mScrollView.smoothScrollTo(0,mSourcing.getTop());
} else if (id == R.id.mono_article_tab_btn_photos) {
mScrollView.smoothScrollTo(0,mPhotos.getTop());
} else if (id == R.id.mono_article_tab_btn_navision) {
mScrollView.smoothScrollTo(0,mNavision.getTop());
} else if (id == R.id.mono_article_tab_btn_general) {
mScrollView.smoothScrollTo(0,mGeneral.getTop());
} else if (id == R.id.mono_article_tab_btn_descriptions) {
mScrollView.smoothScrollTo(0,mDescriptions.getTop());
}
}
};
mScrollView = (ScrollView) rootView.findViewById(R.id.fragment_current_articles_mono_scrollview);
rootView.findViewById(R.id.mono_article_tab_btn_descriptions).setOnClickListener(listener);
rootView.findViewById(R.id.mono_article_tab_btn_general).setOnClickListener(listener);
rootView.findViewById(R.id.mono_article_tab_btn_navision).setOnClickListener(listener);
rootView.findViewById(R.id.mono_article_tab_btn_photos).setOnClickListener(listener);
rootView.findViewById(R.id.mono_article_tab_btn_sourcing).setOnClickListener(listener);
rootView.findViewById(R.id.mono_article_tab_btn_statistiques).setOnClickListener(listener);
// mPhotos = rootView.findViewById(R.id.fragment_current_articles_mono_photos_anchor);
mGeneral = rootView.findViewById(R.id.fragment_current_articles_mono_general_anchor);
mSourcing = rootView.findViewById(R.id.fragment_current_articles_mono_sourcing_anchor);
mNavision = rootView.findViewById(R.id.fragment_current_articles_mono_navision_anchor);
mStatistiques = rootView.findViewById(R.id.fragment_current_articles_mono_statistiques_anchor);
// mDescriptions = rootView.findViewById(R.id.fragment_current_articles_mono_descriptions);
return rootView;
}
我不会发布XML文件,因为它很大。有一些带有TextInputLayout的EditText,TextView,View(用于制作分隔符),我主要使用LinearLayout来格式化它。我也有一些TableLayout。没有ImageView。
我的第二个问题也在于viewpager:我有一个方法用另一个片段替换它,以及用viewpager替换新片段的方法。我不想保存每个片段的状态(包含viewpager的片段包含其他片段,另一个片段包含recyclerview)。我总是调用supportFragmentManager的replace方法,但内存越来越大,直到我得到一个OutOfMemoryException
我用ListArticleFragment替换了上面包含的MonoArticlePagerFragment,它只包含一个没有图片的RecyclerView。
public class ListArticleFragment extends Fragment{
private RecyclerView mRecyclerView;
public static ListArticleFragment newInstance() {
Bundle args = new Bundle();
ListArticleFragment fragment = new ListArticleFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = View.inflate(getActivity(), R.layout.fragment_current_articles_list, null);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_current_articles_list_recylcerview);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(),5);
mRecyclerView.setLayoutManager(gridLayoutManager);
mRecyclerView.setAdapter(new ArticleListAdapter(getActivity(),CurrentArticlesFragment.sListArticles));
return rootView;
}
}
我用这个替换了这个片段:
mActivity.getSupportFragmentManager().beginTransaction()
.replace(R.id.content, ListArticleFragment.newInstance())
.commit();
由于我替换了MonoArticlePagerFragment,我希望他所占用的内存及其包含的片段是免费的,但它似乎并不像那样。 当我切换到MonoArticlePagerFragment(一个全新的实例,不需要维护状态或任何东西)时,我使用这个:
Fragment fragment = MonoArticlePagerFragment.newInstance(mIsNewFragment, mPosition);
mActivity.getSupportFragmentManager().beginTransaction()
.replace(R.id.content, fragment)
.commit();
为什么我的viewpager会保持滚动状态(我估计内存中的片段)以及为什么在第二种情况下会出现OutOfMemoryException?