Android RetainFragment状态保存的方法
一、常见的状态保存恢复方式
①onSaveInstance+onRestoreInstance
这种方式是最通用的实现状态保存与恢复,在Android生态种,组件和View大量使用了此方式。
②android:configChanges+onConfigurationChanged
这种情况适用于屏幕旋转和配置变化,只要作用是阻止Activity重建,因此对于【语言】【时区】的调整可能需要重新启动Activity才能更新。
注意:
语言的变化需要配置为
android:configChanges="locale|layoutDirection"
屏幕旋转需要配置为
android:configChanges="orientation|keyboard|screenSize"
③onRetainNonConfigurationInstance
此方法是3.0版本的Android系统中提供了代替方式②的一种方式,使用场景是允许屏幕旋转、时区和语言调整及时反应。但是对于当前系统的状态或者进行的任务需要进行保存。
如线程任务
publicclassNetWorkTaskextendsThread{
privatevolatileProgressUpdateLinsterprogressUpdateLinster;
privateHandlerhandler=newHandler(Looper.getMainLooper());
publicNetWorkTask(ProgressUpdateLinsterprogressUpdateLinster){
this.progressUpdateLinster=progressUpdateLinster;
}
privateintprogress=0;
@Override
publicvoidrun(){
while(progress<=100){
if(progressUpdateLinster!=null){
handler.post(newRunnable(){
@Override
publicvoidrun(){
progressUpdateLinster.updateProgress(progress);
}
});
}
try{
Thread.sleep(200);
}catch(InterruptedExceptione){
return;
}
progress+=2;
}
}
publicinterfaceProgressUpdateLinster{
voidupdateProgress(intprogress);
}
publicvoidcacel(){
interrupt();
}
publicvoidsetProgressUpdateLinster(ProgressUpdateLinsterprogressUpdateLinster){
this.progressUpdateLinster=progressUpdateLinster;
}
}
在Activity中保存状态
privateProgressBarprogressBar;
privateTextViewtextView;
privatestaticfinalStringTAG="MainActivity";
NetWorkTasknetWorkTask=null;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar=(ProgressBar)findViewById(R.id.progressbar);
textView=(TextView)findViewById(R.id.tv_progroess);
if(getLastCustomNonConfigurationInstance()!=null
&&getLastCustomNonConfigurationInstance()instanceofNetWorkTask){
this.netWorkTask=(NetWorkTask)getLastCustomNonConfigurationInstance();//获取保存的任务
this.netWorkTask.setProgressUpdateLinster(linster);
}else{
this.netWorkTask=newNetWorkTask();
netWorkTask.setProgressUpdateLinster(linster);
netWorkTask.start();
}
}
privateNetWorkTask.ProgressUpdateLinsterlinster=newNetWorkTask.ProgressUpdateLinster(){
@Override
publicvoidupdateProgress(intprogress){
progressBar.setProgress(progress);
textView.setText(progress+"%");
Log.d(TAG,MainActivity.this.toString());
}
};
/**
*保存任务
*/
@Override
publicObjectonRetainCustomNonConfigurationInstance(){
returnnetWorkTask;
}
④RetainFragment
所谓RetainFragment并不是多么高大上的Fragment,和DialogFragment一样本身都是比较普通的,这里的RetainFragment更注重【用途】,而非Fragment的名称。
Fragment同样是Android3.0版本的API,不过support-v4中也提供了补充方式。这种保存状态的原理是将Fragment加入FragmentManager的事务中,但是并不显示到界面中(也不需要实现view),因此可以成为后台Fragment。
要实现后台Fragment,必须做到在Activity重建的时候不被销毁,原理就是通过setRetainInstance方法实现。
publicclassWorkFragmentextendsFragment{
NetWorkTasknetWorkTask=null;
/**
*重建之后这里的Context会自动替换成新的Activity
*@paramcontext
*/
@Override
publicvoidonAttach(Contextcontext){
super.onAttach(context);
//第一次启动的时候,这里network还没有初始化
//Activity重建之后,更新回调
if(netWorkTask!=null){
netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster)context);
}
}
@Override
publicvoidonDetach(){
super.onDetach();
netWorkTask.setProgressUpdateLinster(null);
}
@Override
publicvoidonCreate(@NullableBundlesavedInstanceState){
super.onCreate(savedInstanceState);//重建之后不再会调用此方法
//设置为retaininstanceFragment
setRetainInstance(true);
netWorkTask=newNetWorkTask();
netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster)getActivity());
netWorkTask.start();
}
}
Activity中的使用方式
publicclassMainActivityextendsAppCompatActivityimplementsNetWorkTask.ProgressUpdateLinster{
privateProgressBarprogressBar;
privateTextViewtextView;
privatestaticfinalStringTAG="MainActivity";
privatestaticfinalStringTAG_TASK_FRAGMENT="work";
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar=(ProgressBar)findViewById(R.id.progressbar);
textView=(TextView)findViewById(R.id.tv_progroess);
//如果已经有了workfragment,那就不需要再新建了
if(getSupportFragmentManager().findFragmentByTag(TAG_TASK_FRAGMENT)==null){
getSupportFragmentManager().beginTransaction().add(newWorkFragment(),TAG_TASK_FRAGMENT).commit();
}
}
@Override
publicvoidupdateProgress(intprogress){
progressBar.setProgress(progress);
textView.setText(progress+"%");
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。