activity销毁重建情况下异步任务数据保存恢复
2017-03-24 16:11
447 查看
如果acvitiy销毁时关闭异步任务,不符合常理,如果不关闭异步任务,这样可能更新已经不存在的控件,且对话框关闭dismiss空指针异常。存在这样一种需求,activity被销毁,其后台任务正在进行中,当再次进入activity时,再次显示进度,我们的目标是不对后台任务中断重启,并且对话框正常显示。
1、在fragment中声明要保存的数据。
2、以下相当于进度条:
3、异步任务:
这个异步任务,任务开始显示一个进度条,50s后返回一个数值,并为activity提供回调,因为这里持有activity的引用,这里也提供setActivity方法,acitivity销毁时在onSaveInstanceState中设置setActivity取消之前的对话框,同时也防止了内存泄漏,activity重建时,onCreate中设置setActivity传入新的activity,再次显示加载框。这里注意,activity销毁重建并不影响加载数据,后台数据一直在加载。
4、secondActivity中实现
如果第一次进入,则将activity传递给AsyncTask,开启任务mMyTask并把它交给fragment维护
不正常情况下,如屏幕旋转,activity设置setActvity为null,取消之前的对话框,并在activity重建时framework没有销毁,直接通过get方法去除加载任务mTask,再次显示一个新的加载框。
1、在fragment中声明要保存的数据。
public class FragmentDemo extends Fragment { private MyAsyncTask data; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * setRetainInstance(true),意味着在 Activity 重绘时, * 我们的 Fragment 不会被重复绘制,也就是它会被“保留”,不需要重新创建 */ setRetainInstance(true); } public MyAsyncTask getData() { return data; } public void setData(MyAsyncTask data) { this.data = data; } }
2、以下相当于进度条:
public class LoadingDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.dialog_loading, null); Dialog dialog = new Dialog(getActivity(), R.style.dialog); dialog.setContentView(view); return dialog; } }
3、异步任务:
public class MyAsyncTask extends AsyncTask { private SeconActivity activity; private LoadingDialog mLoadingDialog; boolean isCompleted; private int result; public MyAsyncTask(SeconActivity activity) { this.activity=activity; } @Override protected void onPreExecute() { mLoadingDialog = new LoadingDialog(); mLoadingDialog.show(activity.getFragmentManager(),"LOADING"); } @Override protected Object doInBackground(Object[] params) { result = loadingData(); return null; } @Override protected void onPostExecute(Object o) { isCompleted=true; notifyActivityTaskCompleted(); if (mLoadingDialog!=null){ mLoadingDialog.dismiss(); } } public void setActivity(SeconActivity activity){ //如果上一个activity销毁,将与上一个acitivty绑定的DialogFragment销毁 if (activity ==null){ mLoadingDialog.dismiss(); } //设置为当前的activity this.activity=activity; //开启一个与当前activity绑定的等待框 if (activity!=null&& !isCompleted){ mLoadingDialog = new LoadingDialog(); mLoadingDialog.show(activity.getFragmentManager(),"LOADING"); } //如果完成,通知activity if (isCompleted){ notifyActivityTaskCompleted(); } } private void notifyActivityTaskCompleted() { if (null !=activity){ activity.onTaskComleted(); } } private int loadingData() { // int j=0; try { for (int i=0;i<50;i++){ Thread.sleep(1000); // j=i; Log.e("mrpeng", "loadingData: "+i ); } } catch (InterruptedException e) { e.printStackTrace(); } return 666; } public int getTaskResult() { return result; } }
这个异步任务,任务开始显示一个进度条,50s后返回一个数值,并为activity提供回调,因为这里持有activity的引用,这里也提供setActivity方法,acitivity销毁时在onSaveInstanceState中设置setActivity取消之前的对话框,同时也防止了内存泄漏,activity重建时,onCreate中设置setActivity传入新的activity,再次显示加载框。这里注意,activity销毁重建并不影响加载数据,后台数据一直在加载。
4、secondActivity中实现
public class SeconActivity extends AppCompatActivity { private FragmentDemo fragmentDemo; private MyAsyncTask mMyTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("mrpeng", "SeconActivity-=-=-=-onCreate: "); FragmentManager fm = getFragmentManager(); fragmentDemo = (FragmentDemo) fm.findFragmentByTag("data"); if (fragmentDemo==null){ fragmentDemo=new FragmentDemo(); fm.beginTransaction().add(fragmentDemo,"data").commit();// } mMyTask = fragmentDemo.getData(); if (mMyTask!=null){ mMyTask.setActivity(this); }else { mMyTask=new MyAsyncTask(this); mMyTask.execute(); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { mMyTask.setActivity(null); super.onSaveInstanceState(outState); } public void onTaskComleted() { int taskResult = mMyTask.getTaskResult(); Toast.makeText(this,"taskResult :::"+taskResult,Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { Log.e("mrpeng", "SeconActivity-=-=-=-onDestroy: "); super.onDestroy(); } }
如果第一次进入,则将activity传递给AsyncTask,开启任务mMyTask并把它交给fragment维护
不正常情况下,如屏幕旋转,activity设置setActvity为null,取消之前的对话框,并在activity重建时framework没有销毁,直接通过get方法去除加载任务mTask,再次显示一个新的加载框。
相关文章推荐
- Android开发——Activity销毁时异步任务的保存和恢复、以及相关的进度条的显示问题
- 异常情况下Activity数据的保存和恢复
- Android中突发情况Activity数据的保存和恢复
- activity 生命周期发生变化的时候,用fragment保存数据或者异步任务数据的文章
- Android中突发情况Activity数据的保存和恢复
- Activity销毁重建数据恢复的两种办法
- android笔记--保存和恢复activity的状态数据
- 【转】android笔记--保存和恢复activity的状态数据
- 使用onSaveInstanceState和onRestoreInstanceState来保存恢复被系统销毁的数据
- Activity的突发情况下退出恢复数据
- android笔记--保存和恢复activity的状态数据
- 保存和恢复activity的状态数据
- android笔记--保存和恢复activity的状态数据
- Android中突发情况数据的保存和恢复
- Android开发之保存和恢复Activity的状态与数据
- Android activity 开启时数据保存和恢复
- android笔记--保存和恢复activity的状态数据
- 保存和恢复activity的状态数据
- android保存和恢复activity的状态数据
- 安卓性能优化之Activity和Fragment通过onSaveInstanceState()保存和恢复数据