Android RetainFragment状态保存的方法

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • android中Activity详解(生命周期、以各种方式启动Activity、状态保存,完全退出等)

    一.什么是Activity? 简单的说:Activity就是布满整个窗口或者悬浮于其他窗口上的交互界面.在一个应用程序中通常由多个Activity构成,都会在Manifestxml中指定一个主的Activity,如下设置 <actionandroid:name="AndroidintentactionMAIN" /> 当程序第一次运行时用户就会看这个Activity,这个Activity可以通过启动其他的Activity进行相关操作.当启动其他的Activity时这个当前的

  • Android编程实现状态保存的方法分析

    本文实例讲述了Android编程实现状态保存的方法.分享给大家供大家参考,具体如下: 1.当我们正在发短信的时候,已经写了几百字了,这时突然来了一个电话,我们接完电话之后,如果发现辛辛苦苦的几百字不见了,那可就火大了,而实际上这些内容都是保存了的.在我们接电话的过程中,我们发信息的那个Activity是可能会被系统回收的,这时会调用Activity的onSaveInstanceState回调方法,而我们就可以在这个方法中保存状态数据,在onCreate方法或者在2.0之后提供的回调方法onRes

  • Android RetainFragment状态保存的方法

    一.常见的状态保存恢复方式 ①onSaveInstance + onRestoreInstance 这种方式是最通用的实现状态保存与恢复,在Android生态种,组件和View大量使用了此方式. ②android:configChanges+onConfigurationChanged 这种情况适用于屏幕旋转和配置变化,只要作用是阻止Activity重建,因此对于[语言][时区]的调整可能需要重新启动Activity才能更新. 注意: 语言的变化需要配置为 android:configChang

  • Android中用onSaveInstanceState保存Fragment状态的方法

    在Fragment里面,利用onSaveInstanceState保存数据,并可在onActivityCreated里面恢复数据. public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ... if (savedInstanceState != null) { // Restore the fragment's state here } } p

  • Android开发SavedState Jetpack状态保存利器

    目录 背景 SavedState的登场 理解SavedState 用法 SavedState组成概念 原理探究 最后 背景 在我们android开发中,如果需要actiivty/fragment等有状态的控件保存当前状态,由系统进行数据保存的恢复的时候 比如正常的暗黑模式切换/后台时低内存系统回收等等,都需要我们对当前的用户数据进行保存,不然下次重新恢复的时候,就会出现丢失数据的情况,给用户造成不太好的体验 一般都会重写onSaveInstanceState方法进行,在里面的Bundle对象进行

  • Android编程监听网络连接状态改变的方法

    本文实例讲述了Android编程监听网络连接状态改变的方法.分享给大家供大家参考,具体如下: BroadcastReceiver public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub //Toast.makeText(context, intent

  • Android将String保存为SD卡中TXT文件的方法

    如下所示: public static void stringTxt(String str){ try { FileWriter fw = new FileWriter("/sdcard/aaa" + "/cmd.txt");//SD卡中的路径 fw.flush(); fw.write(str); fw.close(); } catch (Exception e) { e.printStackTrace(); } } 以上这篇Android将String保存为SD卡

  • Android中startService基本使用方法概述

    Android中有两种主要方式使用Service,通过调用Context的startService方法或调用Context的bindService方法,本文只探讨纯startService的使用,不涉及任何bindService方法调用的情况.如果想了解bindService的相关使用,请参见<Android中bindService基本使用方法概述>. 当我们通过调用了Context的startService方法后,我们便启动了Service,通过startService方法启动的Servic

  • Android 网络状态实时监听代码实例(一)

    其实手机在网络方面的的监听也比较重要,有时候我们必须实时监控这个程序的实时网络状态,android在网络断开与连接的时候都会发出广播,我们通过接收系统的广播就可以实现网络的监听. 1.添加访问网络和获取网络状态的权限 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permissio

  • Android intent之间复杂参数传递方法详解

    本文详细讲述了Android intent之间复杂参数传递方法.分享给大家供大家参考,具体如下: Intent是Activity与Activity之间,Activity与Service之间传递参数的介质,而这两种通常实现的是Java基本对象类型和String的传递. 在实际项目中,页面之间传值,除了以上几种,经常还有传递Object对象.List类型.List<Object>类型和全局变量等等的需求.本文就是介绍怎么传递这几种类型的参数. 一.传递List<String>和List

  • Android实现离线缓存的方法

    离线缓存就是在网络畅通的情况下将从服务器收到的数据保存到本地,当网络断开之后直接读取本地文件中的数据.如Json 数据缓存到本地,在断网的状态下启动APP时读取本地缓存数据显示在界面上,常用的APP(网易新闻.知乎等等)都是支持离线缓存的,这样带来了更好的用户体验. 如果能够在调用网络接口后自动缓存返回的Json数据,下次在断网状态下调用这个接口获取到缓存的Json数据的话,那该多好呢?Volley做到了这一点. 因此,今天这篇文章介绍的就是使用Volley自带的数据缓存,配合Universal

随机推荐