欢迎来到代码驿站!

Android代码

当前位置:首页 > 移动开发 > Android代码

Android RetainFragment状态保存的方法

时间:2020-10-18 11:01:41|栏目:Android代码|点击:

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

①onSaveInstance + onRestoreInstance

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

②android:configChanges+onConfigurationChanged

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

注意:

语言的变化需要配置为

android:configChanges="locale|layoutDirection"

屏幕旋转需要配置为

android:configChanges="orientation|keyboard|screenSize"

③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+"%");
}
}

上一篇:Windows下搭建Android开发环境

栏    目:Android代码

下一篇:Android中ListView Item布局优化技巧

本文标题:Android RetainFragment状态保存的方法

本文地址:http://www.codeinn.net/misctech/12996.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有