if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, “Removing item #” + position + “: f=” + object
- " v=" + ((Fragment)object).getView());
while (mSavedState.size() <= position) {
mSavedState.add(null);
}
mSavedState.set(position, fragment.isAdded()
? mFragmentManager.saveFragmentInstanceState(fragment) : null);
mFragments.set(position, null);
mCurTransaction.remove(fragment);
if (fragment == mCurrentPrimaryItem) {
mCurrentPrimaryItem = null;
}
}
其中核心代码是:
mCurTransaction.remove(fragment);
FragmentStatePagerAdapter会销毁不需要的fragment。事务提交后, activity的FragmentManager中的fragment会被彻底移除。 FragmentStatePagerAdapter类名中的“state”表明:在销毁fragment时,可在onSaveInstanceState(Bundle)方法中保存fragment的Bundle信息。用户切换回来时,保存的实例状态可用来恢复生成新的fragment。
- 当页面比较少、简单时,一般选择FragmentPagerAdapter;
解析:当直接使用PagerAdapter时,必须重写destroyItem方法,FragmentPagerAdapter已经为我们写好destroyItem的实现,源码如下:
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
Fragment fragment = (Fragment) object;
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, “Detaching item #” + getItemId(position) + “: f=” + object
- " v=" + (fragment.getView()));
mCurTransaction.detach(fragment);
if (fragment == mCurrentPrimaryItem) {
mCurrentPrimaryItem = null;
}
}
其核心代码是:
mCurTransaction.detach(fragment);
对于不再需要的fragment,FragmentPagerAdapter会选择调用事务的detach()方法来处理它,而非remove()方法。也就是说, FragmentPagerAdapter只是销毁了fragment的视图, fragment实例还保留在FragmentManager中。因此,FragmentPagerAdapter创建的fragment永远不会被销毁。
- 当页面需要刷新时,选择FragmentStatePagerAdapter;
解析:
如果使用FragmentPagerAdapter,Fragment对象一般不会被销毁的,这时需要修改ViewPager适配器中的传值,再调用以下方法刷新数据
myPagerAdapter2.notifyDataSetChanged();
但是,如果ViewPager页面比较多时,内存中会有大量的Fragment对象无法释放,浪费了内存。另外,由于ViewPager的自身特性,在内存中默认存在3个页面,其余页面会自动销毁,这样导致的情况是:ViewPager页面销毁了,但是对应的Fragment对象没有被销毁,我认为这是一个严重的内存泄漏现象。
如果使用FragmentStatePagerAdapter的话,当ViewPager页面被销毁时,Fragment对象也会被销毁,就不存在这样的内存泄漏问题。
【基本代码实现】
MyPagerAdapter2.java
public class MyPagerAdapter2 extends FragmentStatePagerAdapter {
private Context mContext;
private List myPagerFragmentList;
public MyPagerAdapter2(Context context , List list, @NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
mContext = context;
myPagerFragmentList = list;
}
@Override
public int getCount() {
return myPagerFragmentList.size();
}
@NonNull
@Override
public Fragment getItem(int position) {
return myPagerFragmentList.get(position);
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
super.destroyItem(container, position, object);
}
}
MyPagerFragment.java
public class MyPagerFragment extends Fragment {
String mContent;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContent = (String) getArguments().get(“content”);
View view = inflater.inflate(R.layout.item_base, container, false) ;
TextView textView = (TextView) view.findViewById(R.id.tv);
textView.setText(mContent);
学习福利
【Android 详细知识点思维脑图(技能树)】
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
- 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
[外链图片转存中…(img-WA1EevzO-1715879358928)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!