比较简单,只需要声明需要保存的数据对象,然后提供getter和setter,注意,一定要在onCreate调用setRetainInstance(true);
然后是:FragmentRetainDataActivity
package com.example.zhy_handle_runtime_change;
import Android.app.Activity;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.Volley;
public class FragmentRetainDataActivity extends Activity
{
private static final String TAG = "FragmentRetainDataActivity";
 private RetainedFragment dataFragment;
 private DialogFragment mLoadingDialog;
 private ImageView mImageView;
 private Bitmap mBitmap;
@Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Log.e(TAG, "onCreate");
// find the retained fragment on activity restarts
  FragmentManager fm = getFragmentManager();
  dataFragment = (RetainedFragment) fm.findFragmentByTag("data");
  // create the fragment and data the first time
  if (dataFragment == null)
  {
   // add the fragment
   dataFragment = new RetainedFragment();
   fm.beginTransaction().add(dataFragment, "data").commit();
  }
  mBitmap = collectMyLoadedData();
  initData();
// the data is available in dataFragment.getData()
 }
/**
  * 初始化数据
  */
 private void initData()
 {
  mImageView = (ImageView) findViewById(R.id.id_imageView);
  if (mBitmap == null)
  {
   mLoadingDialog = new LoadingDialog();
   mLoadingDialog.show(getFragmentManager(), "LOADING_DIALOG");
   RequestQueue newRequestQueue = Volley
     .newRequestQueue(FragmentRetainDataActivity.this);
   ImageRequest imageRequest = new ImageRequest(
     "upload/2015_08/150808110773613.jpg",
     new Response.Listener<Bitmap>()
     {
      @Override
      public void onResponse(Bitmap response)
      {
       mBitmap = response;
       mImageView.setImageBitmap(mBitmap);
       // load the data from the web
       dataFragment.setData(mBitmap);
       mLoadingDialog.dismiss();
      }
     }, 0, 0, Config.RGB_565, null);
   newRequestQueue.add(imageRequest);
  } else
  {
   mImageView.setImageBitmap(mBitmap);
  }
}
@Override
 public void onDestroy()
 {
  Log.e(TAG, "onDestroy");
  super.onDestroy();
  // store the data in the fragment
  dataFragment.setData(mBitmap);
 }
private Bitmap collectMyLoadedData()
 {
  return dataFragment.getData();
 }
}
这里在onCreate总使用了Volley去加载 了一张美女照片,然后在onDestroy中对Bitmap进行存储,在onCreate添加一个或者恢复一个Fragment的引用,然后对Bitmap进行读取和设置。这种方式适用于比较大的数据的存储与恢复。
注:这里也没有考虑加载时旋转屏幕,问题与上面的一致。
效果图:

5、配置configChanges,自己对屏幕旋转的变化进行处理
在menifest中进行属性设置:
<activity
            android:name=".ConfigChangesTestActivity"
            android:configChanges="screenSize|orientation" >
        </activity>
低版本的API只需要加入orientation,而高版本的则需要加入screenSize。
ConfigChangesTestActivity
package com.example.zhy_handle_runtime_change;
import java.util.ArrayList;
import java.util.Arrays;
import android.app.DialogFragment;
import android.app.ListActivity;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.Toast;
/**
 * @author zhy
 * 
 */
public class ConfigChangesTestActivity extends ListActivity
{
 private static final String TAG = "MainActivity";
 private ListAdapter mAdapter;
 private ArrayList<String> mDatas;
 private DialogFragment mLoadingDialog;
 private LoadDataAsyncTask mLoadDataAsyncTask;
@Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  Log.e(TAG, "onCreate");
  initData(savedInstanceState);
 }
/**
  * 初始化数据
  */
 private void initData(Bundle savedInstanceState)
 {
mLoadingDialog = new LoadingDialog();
  mLoadingDialog.show(getFragmentManager(), "LoadingDialog");
  mLoadDataAsyncTask = new LoadDataAsyncTask();
  mLoadDataAsyncTask.execute();
}
/**
  * 初始化适配器
  */
 private void initAdapter()
 {
  mAdapter = new ArrayAdapter<String>(ConfigChangesTestActivity.this,
    android.R.layout.simple_list_item_1, mDatas);
  setListAdapter(mAdapter);
 }
/**
  * 模拟耗时操作
  * 
  * @return
  */
 private ArrayList<String> generateTimeConsumingDatas()
 {
  try
  {
   Thread.sleep(2000);
  } catch (InterruptedException e)
  {
  }
  return new ArrayList<String>(Arrays.asList("通过Fragment保存大量数据",
    "onSaveInstanceState保存数据",
    "getLastNonConfigurationInstance已经被弃用", "RabbitMQ", "Hadoop",
    "Spark"));
 }
/**
  * 当配置发生变化时,不会重新启动Activity。但是会回调此方法,用户自行进行对屏幕旋转后进行处理
  */
 @Override
 public void onConfigurationChanged(Configuration newConfig)
 {
  super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
  {
   Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
  } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
  {
   Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
  }
}
private class LoadDataAsyncTask extends AsyncTask<Void, Void, Void>
 {
  @Override
  protected Void doInBackground(Void... params)
  {
   mDatas = generateTimeConsumingDatas();
   return null;
  }
@Override
  protected void onPostExecute(Void result)
  {
   mLoadingDialog.dismiss();
   initAdapter();
  }
 }
@Override
 protected void onDestroy()
 {
  Log.e(TAG, "onDestroy");
  super.onDestroy();
 }
}
对第一种方式的代码进行了修改,去掉了保存与恢复的代码,重写了onConfigurationChanged;此时,无论用户何时旋转屏幕都不会重新启动Activity,并且onConfigurationChanged中的代码可以得到调用。从效果图可以看到,无论如何旋转不会重启Activity.
效果图:


