Android开发之多Fragment切换优化
问题分析
一直在简书里看别人的技术贴,今天我也来写点自己的心得!最近在写一个项目用到大量的Fragment后的总结!
我想刚刚接触安卓的同学或许会这么写:
FragmentManager fragmentManager=getSupportFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
fragmentTransaction.add(ViewId,fragment);// 或者fragmentTransaction.replace(ViewId,fragment);
fragmentTransaction.commit();
基础更好一点的同学会用show和hide方法
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.hide(new FirstFragment())
.show(new SecondFragment())
.commit();
诚然这两种都可以切换Fragment,但是面对用户大量点击来回切换,或者你的Fragment本来就很多,每次都这样操作,那么很快你的应用就会OOM,就算不崩那也会异常的卡顿!so why?
当我们replace时发生了以下的生命周期:

想想看每次都replace一下!!这世界会有多美好!!!那么问题出在哪?回过头看看代码就会发现每次在add/replace或者show/hide都会new 一个新的实例,这就是致命原因!!!!!
废话少说,开始优化
方案一:
预加载模式:
//首先需要先实例好三个全局Fragment FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment, FirstFragment.getInstance());
ft.add(R.id.fragment, SecondFragment.getInstance());
ft.add(R.id.fragment, ThirdFragment.getInstance());
ft.hide(SecondFragment.getInstance());
ft.hide(ThirdFragment.getInstance());
ft.commit();
在加载第一个Fragment时就把全部Fragment加载好,下次使用直接调用如:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.hide(FirstFragment.getInstance())
.show(SecondFragment.getInstance())
.commit();
是不是总觉怪怪的,虽然比之前的代码好,但是这种做法很Java,当然需要预加载的朋友依然是不二之选!!!
那有没有更好的方法呢?答案是肯定的
方案二:
动态加载模式:
//首先需要先实例好n个全局Fragment
//private Fragment currentFragment=new Fragment();(全局)
private FragmentTransaction switchFragment(Fragment targetFragment) {
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
if (!targetFragment.isAdded()) {
//第一次使用switchFragment()时currentFragment为null,所以要判断一下
if (currentFragment != null) {
transaction.hide(currentFragment);
}
transaction.add(R.id.fragment, targetFragment,targetFragment.getClass().getName());
} else {
transaction
.hide(currentFragment)
.show(targetFragment);
}
currentFragment = targetFragment;
return transaction;
}
在点击切换Fragment时:
@Override
public void onTabSelected(@IdRes int tabId) {
if (tabId == R.id.tab_one){
switchFragment(first).commit();
}
if (tabId == R.id.tab_two){
switchFragment(second).commit();
}
if (tabId == R.id.tab_three){
switchFragment(third).commit();
}
}
现在你的Fragment无论怎么切都不会出现卡顿了,因为你的所有Fragment只会被实例化一次!实例一次的Fragment会被存入内存中,下次切换会判断内存中是否含有要切换的Fragment,如果有就直接复用,没有就add一个新的!优化大法完成!
外番
WHAT?等等!只实例一次,那我的Fragment里的数据要更新怎么办?我的回答是——软件关了再次重启!

要是这样,这样的软件真的要逆天了!好在官方提供了onHiddenChanged方法,每次切换hide或者show时该方法会被执行,可以在这里面更新数据!
//此方法在Fragment中
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden){
//Fragment隐藏时调用
}else {
//Fragment显示时调用
}
}
此方法是不是比每次add或replace更新数据执行一大坨的生命周期要优雅的多的多!
GitHub地址:FragmentDemo (欢迎 fork 和 star)
注:提醒小白(老手请忽略)
此demo只供fragment理解,此样例app的业务逻辑建议ViewPager+Fragment或者其他。。。
作者:8金木研8
链接:https://www.jianshu.com/p/4c5f015b3b6c
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
Android开发之多Fragment切换优化的更多相关文章
- 【转】Android开发之Bitmap的内存优化详解
本文来源:转载自: http://mobile.51cto.com/abased-410796.htm 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitma ...
- android开发之merge结合include优化布局
merge结合include优化android布局,效果不知道,个人感觉使用上也有很大的局限,不过还是了解一下,记录下来. 布局文件都要有根节点,但android中的布局嵌套过多会造成性能问题,于是在 ...
- Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...
- Android开发之InstanceState详解
Android开发之InstanceState详解 本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...
- Android开发之Java必备基础
Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...
- Android开发之InstanceState详解(转)---利用其保存Activity状态
Android开发之InstanceState详解 本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...
- Android开发之eclipse 快捷键
转自:<Android开发之eclipse 快捷键>http://www.cnblogs.com/aimeng/archive/2012/08/07/2626909.html Ctrl+1 ...
- Android开发之旅3:android架构
引言 通过前面两篇: Android 开发之旅:环境搭建及HelloWorld Android 开发之旅:HelloWorld项目的目录结构 我们对android有了个大致的了解,知道如何搭建andr ...
- Android开发之JNI(一)--HelloWorld及遇到的错误解析
Android开发之JNI(一)--HelloWorld及遇到的错误解析 1.NDK环境搭建 參考http://blog.csdn.net/xiaoliouc/article/details/8 ...
随机推荐
- jQuery中json中关于带有html代码网页的处理
昨天在使用jQuery的get方式请求返回json格式数据.然后使用jQuery自带的parseJSON 处理.总是出现这样的错误. 如果返回数据中content改成普通的数据可以通过.找了半天错误, ...
- 基于 Django 2.0.4 的 djcelery 配置
Django Celery 配置实践 所需环境 python 3.5.2 rabbitmq 安装所需的包 pip install -r requirements.txt QuickStart 创建Dj ...
- python 数据类型 datatype
python 数据类型 datatype 列表list 元组tuple 集合set 字典dictionary 字符串string 一.列表list list :python的一种数据类型.是可变的, ...
- item2乱码问题
使用的是 mac 环境,本地使用终端打开中文可以正常显示,但是连接远端服务器上发现就编程乱码了,之前一直是好好的,但是突然有一天开始就乱码了,怀疑是我电脑升级后导致系统环境配置发生变化引起的.直接上解 ...
- 9、JPA-映射-双向多对多
实体类 Category package com.jpa.yingshe; import java.util.HashSet; import java.util.Set; import javax.p ...
- 学习windows编程 day4 之 多边矩形填充
#include <windows.h> #include <math.h> LRESULT CALLBACK WndProc(HWND hwnd, UINT message, ...
- vue项目中使用scss
npm install sass-loader node-sass --save-dev
- JAVA记录-Mybatis介绍
1.什么是 MyBatis ? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyB ...
- UVALive - 7637 E - Balanced String(构造)
原题链接 题意:给出一个打乱顺序的序列,问是否能构造出一个括号匹配的字符串.每个数字为此前读取到的左括号数减去右括号数. 分析:有左括号开始构造,不够的话就找右括号.注意特殊情况待处理.详情看代码 # ...
- JavaScript中的number跟string
遇到问题困扰很久,因为这看起来木有问题,都是对的啊,殊不知是因为参数需要一个数字类型,但是数据却悄悄变成了字符类型.在群里求救无果最后自己找到了原因. 为什么我箭头里放数字可以正常显示,放temp[i ...