activity被回收,fragment恢复处理
例如activity放在后台一段时间,当activity被回收之后,再重新进入activity的时候,会重新调用onCreate(),并且savedInstanceState不再是null,因此可以判断出是否被回收。onCreate中不要重复创建fragment,通过tag去获得fagment即可@Overrideprotected void onCreate(Bundle sa
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了。
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)