activity被回收,fragment恢复处理
来源:互联网 发布:淘宝男裤子店铺排名 编辑:程序博客网 时间:2024/04/30 07:31
onCreate中不要重复创建fragment,通过tag去获得figment即可。
从谷歌开源项目中得到的的启示,源码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewResId()); if (getIntent().hasExtra(Intent.EXTRA_TITLE)) { setTitle(getIntent().getStringExtra(Intent.EXTRA_TITLE)); } final String customTitle = getIntent().getStringExtra(Intent.EXTRA_TITLE); setTitle(customTitle != null ? customTitle : getTitle()); if (savedInstanceState == null) { mFragment = onCreatePane(); mFragment.setArguments(intentToFragmentArguments(getIntent())); getFragmentManager().beginTransaction() .add(R.id.root_container, mFragment, "single_pane") .commit(); } else { mFragment = getFragmentManager().findFragmentByTag("single_pane"); } }源码摘自:
com.google.samples.apps.iosched.ui.SimpleSinglePaneActivity
自己精简一下就是:
public class MainActivity extends AppCompatActivity { private BlankFragment mFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { mFragment = new BlankFragment(); getSupportFragmentManager().beginTransaction() .add(R.id.root_container, mFragment, "single_pane") .commit(); } else { mFragment = (BlankFragment) getSupportFragmentManager().findFragmentByTag("single_pane"); } Log.e("MainActivity", "savedInstanceState=" + savedInstanceState + " mFragment=" + mFragment); }}
打印了两个Log,一个是首次创建,另一个是回收了之后创建。
11-22 12:55:43.940 24433-24433/com.example.baidu.test E/MainActivity: savedInstanceState=null mFragment=BlankFragment{585c98a id=0x7f0b0055 single_pane}
测试的时候可以设置手机【不保留活动】,这样可以快速的模拟回收的情况,小米手机有这个功能。
Activity被回收,系统为什么会保存Fragment呢?来分析一下FragmentActivity源码:
/**
* Save all appropriate fragment state. */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Parcelable p = mFragments.saveAllState(); if (p != null) { outState.putParcelable(FRAGMENTS_TAG, p);//这里保存了Fragment数据 } if (mPendingFragmentActivityResults.size() > 0) { outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex); int[] requestCodes = new int[mPendingFragmentActivityResults.size()]; String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()]; for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) { requestCodes[i] = mPendingFragmentActivityResults.keyAt(i); fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i); } outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes); outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos); } }从源码中得知,当Activity调用onSaveInstanceState方法的时候,会保存当前Activity里面的所有Fragment,保存在了一个Bundle里,key就是FRAGMENTS_TAG。
其实这个Bundle会在Activity恢复的时候传给onCreate,这就是为什么onSaveInstanceState不是null了。
有人会问什么时候会调用onSaveInstanceState方法?用最简洁的一句话:当Activity不可见的时候就会执行nSaveInstanceState。例如被另一个Activity覆盖,按Home键回到桌面等等。当然你主动结束Activity不会执行。调用onSaveInstanceState保存的不只是fragment,还保存了View的状态,只保存了带id的View的状态,不带id不会保存的。
其实回收之后恢复是很麻烦的,得到了Fragment后,你会发现成员变量并没有恢复,只有View某些状态被恢复了,如果完全重现被回收那一刻的所有状态,还需要考虑在Fragment里面重写onSaveInstanceState方法,来保存一些数据,呵呵,工作量不小啊,非特殊情况下,我不建议这么做。
我一般的做法都是重新创建Activity和Fragment:
public class MainActivity extends AppCompatActivity { static final String FRAGMENTS_TAG = "android:support:fragments"; private BlankFragment mFragment; @Override protected void onCreate(Bundle savedInstanceState) { //删除保存的Fragment,也可以重写onSaveInstanceState方法不让其保存 if (savedInstanceState != null) { savedInstanceState.putParcelable(FRAGMENTS_TAG, null); } super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mFragment = new BlankFragment(); getSupportFragmentManager().beginTransaction() .add(R.id.root_container, mFragment, "single_pane") .commit(); }}
你可以记住重要的关键信息,来恢复这个Activiy。例如当前Activity是一篇文章,你只需要在onSaveInstanceState保存文章id,等恢复的时候直接根据id从服务器拉取就好了。
如果你的Activity在启动时的Intent里面有文章id,那就简单了,在回收恢复的时候,直接这样仍然得到文章id:String id = getIntent().getStringExtra("article_id");,这样根本不用你主动保存。使用Intent的时候必须序列化的原因:只有被序列化的对象和基本数据类型才可以保存在磁盘上,这样内存被干掉,仍然可以将他们从磁盘上恢复到内存中。
0 0
- activity被回收,fragment恢复处理
- 关于fragment,activity被回收之后重新恢复
- Android 管理多个fragment(处理Activity被回收的情况)
- 关于Activity和Fragment的规范使用和系统回收activity的处理
- Android Activity被回收后的处理
- Activity 被回收之后,Fragment的堆栈变化
- Activity 被回收之后,Fragment中 getActivity返回null
- Activity被回收导致fragment的getActivity为空
- Activity被回收后,重建时Fragment重叠问题
- Activity被回收导致其内部的Fragment
- Activity被回收后Fragment嵌套的Fragment不显示问题
- Activity回收时候fragment的异常
- 资源回收导致重建 Activity和 Fragment
- Activity回收时候fragment的异常
- activity使用fragment transaction.commit()进行fragment切换,activity被系统回收后再点应用就无法切换
- activity使用fragment transaction.commit()进行fragment切换,activity被系统回收后再点应用就无法切换
- 处理viewpager、fragment的回收问题
- Activity被回收导致被绑定Fragment调用getActivity()抛空指针异常
- 一步步搭建web服务器(3)
- 七层登陆的华丽转身
- Android FloatMath.ceil过时的解决办法
- 如何用adb查看android终端分辨率?
- Linux下安装Nginx
- activity被回收,fragment恢复处理
- 创建第一个ionic APP项目
- Notepad++中zen-Coding使用
- Android ToolBar 基本使用
- Objective-C多个UIButton同时点击问题
- LeetCode 204 Count Primes(质数计数)(*)
- PHP学习(3)—在HTML中嵌入PHP
- java常用工具类之DES和Base64加密解密类
- Codeforces Round #341 (Div. 2) problemE Wet Shark and Blocks 矩阵乘法 dp