您的位置:首页 > 其它

activity销毁重建情况下异步任务数据保存恢复

2017-03-24 16:11 447 查看
如果acvitiy销毁时关闭异步任务,不符合常理,如果不关闭异步任务,这样可能更新已经不存在的控件,且对话框关闭dismiss空指针异常。存在这样一种需求,activity被销毁,其后台任务正在进行中,当再次进入activity时,再次显示进度,我们的目标是不对后台任务中断重启,并且对话框正常显示。

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,再次显示一个新的加载框。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: