Android RetainFragment状态保存


声明:本文转载自https://my.oschina.net/ososchina/blog/1615579,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

一、常见的状态保存恢复方式

①onSaveInstance + onRestoreInstance

这种方式是最通用的实现状态保存与恢复,在Android生态种,组件和View大量使用了此方式。

②android:configChanges+onConfigurationChanged

这种情况适用于屏幕旋转和配置变化,只要作用是阻止Activity重建,因此对于【语言】【时区】的调整可能需要重新启动Activity才能更新。

③onRetainNonConfigurationInstance

此方法是3.0版本的Android系统中提供了代替方式②的一种方式,使用场景是允许屏幕旋转、时区和语言调整及时反应。但是对于当前系统的状态或者进行的任务需要进行保存。

如线程任务

public class NetWorkTask extends Thread {     private volatile ProgressUpdateLinster progressUpdateLinster;     private Handler handler = new Handler(Looper.getMainLooper());      public NetWorkTask(ProgressUpdateLinster progressUpdateLinster) {         this.progressUpdateLinster = progressUpdateLinster;     }      private int progress = 0;     @Override     public void run() {         while (progress <= 100) {             if(progressUpdateLinster != null) {                 handler.post(new Runnable() {                  @Override                     public void run() {                         progressUpdateLinster.updateProgress(progress);                     }                 });             }             try {                 Thread.sleep(200);             } catch (InterruptedException e) {                 return;             }             progress += 2;         }     }      public interface ProgressUpdateLinster {         void updateProgress(int progress);     }      public void cacel() {         interrupt();     }     public void setProgressUpdateLinster(ProgressUpdateLinster progressUpdateLinster) {           this.progressUpdateLinster = progressUpdateLinster;     } }  

在Activity中保存状态

private ProgressBar progressBar; private TextView textView; private static final String TAG = "MainActivity";  NetWorkTask netWorkTask = null; @Override protected void onCreate(Bundle savedInstanceState) {     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() instanceof NetWorkTask) {          this.netWorkTask = (NetWorkTask) getLastCustomNonConfigurationInstance(); //获取保存的任务         this.netWorkTask.setProgressUpdateLinster(linster);     }else {         this.netWorkTask = new NetWorkTask();         netWorkTask.setProgressUpdateLinster(linster);         netWorkTask.start();     }  }  private NetWorkTask.ProgressUpdateLinster linster = new NetWorkTask.ProgressUpdateLinster() {     @Override     public void updateProgress(int progress) {         progressBar.setProgress(progress);         textView.setText(progress+"%");         Log.d(TAG,MainActivity.this.toString());     } };  /** * 保存任务 */ @Override public Object onRetainCustomNonConfigurationInstance() {     return netWorkTask; }  

④RetainFragment

所谓RetainFragment并不是多么高大上的Fragment,和DialogFragment一样本身都是比较普通的,这里的RetainFragment更注重【用途】,而非Fragment的名称。

Fragment同样是Android 3.0 版本的API,不过support-v4中也提供了补充方式。这种保存状态的原理是将Fragment加入FragmentManager的事务中,但是并不显示到界面中(也不需要实现view),因此可以成为后台Fragment。

要实现后台Fragment,必须做到在Activity重建的时候不被销毁,原理就是通过setRetainInstance方法实现。

public class WorkFragment extends Fragment {   NetWorkTask netWorkTask = null;  /**  * 重建之后这里的Context会自动替换成新的Activity  * @param context  */ @Override public void onAttach(Context context) {     super.onAttach(context);     //第一次启动的时候,这里network还没有初始化     //Activity重建之后,更新回调     if(netWorkTask != null) {         netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster) context);     } }  @Override public void onDetach() {     super.onDetach();     netWorkTask.setProgressUpdateLinster(null); }  @Override public void onCreate(@Nullable Bundle savedInstanceState) {     super.onCreate(savedInstanceState); //重建之后不再会调用此方法     //设置为retain instance Fragment     setRetainInstance(true);     netWorkTask = new NetWorkTask();     netWorkTask.setProgressUpdateLinster((NetWorkTask.ProgressUpdateLinster) getActivity());     netWorkTask.start(); } }  

Activity中的使用方式

public class MainActivity extends AppCompatActivity implements NetWorkTask.ProgressUpdateLinster {  private ProgressBar progressBar; private TextView textView; private static final String TAG = "MainActivity"; private static final String TAG_TASK_FRAGMENT = "work";  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     progressBar = (ProgressBar) findViewById(R.id.progressbar);     textView = (TextView) findViewById(R.id.tv_progroess);          //如果已经有了work fragment,那就不需要再新建了     if(getSupportFragmentManager().findFragmentByTag(TAG_TASK_FRAGMENT) == null) {         getSupportFragmentManager().beginTransaction().add(new WorkFragment(),TAG_TASK_FRAGMENT).commit();     } }  @Override public void updateProgress(int progress) {     progressBar.setProgress(progress);     textView.setText(progress+"%"); } } 

 

 

 

 

本文发表于2018年01月30日 22:32
(c)注:本文转载自https://my.oschina.net/ososchina/blog/1615579,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 674 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

行业标准总是平庸的

一直到现在我才突然明白,我梦寐以求,是真爱和自由。

把爱情留给我身边最真心的姑娘,你陪我歌唱陪我流浪,陪我两败俱伤。

把青春献给身后那座辉煌的都市,为了这个美梦,我们付出着代价。

又是一年五一,祝我们工人阶级劳动节快乐! 今年被困在北京了,离境再入境需要隔离十五天。只能京津冀周边走一走了,想出去玩啊啊啊啊啊~

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1