我有一个进度对话框(使用DialogFragment
实现)重新保留在保留的实例片段中。
如果没有配置更改,DialogFragment
可以被解除而不会出现任何问题。
但是,如果配置发生变化,调用dismiss
将不会产生任何影响。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
BackupTaskFragment backupTaskFragment = BackupTaskFragment.newInstance();
FragmentManager fm = getFragmentManager();
Fragment oldFragment = fm.findFragmentByTag("BACKUP_TASK_FRAGMENT");
if (oldFragment != null) {
fm.beginTransaction().remove(oldFragment).commit();
}
fm.beginTransaction().add(backupTaskFragment, "BACKUP_TASK_FRAGMENT").commit();
}
}
}
public class BackupTaskFragment extends Fragment {
public static final class BackupTaskDialogFragment extends DialogFragment {
public static BackupTaskDialogFragment newInstance() {
return new BackupTaskDialogFragment();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
ProgressDialog progressDialog = new ProgressDialog(this.getActivity());
progressDialog.setMessage("Backup...");
progressDialog.setCanceledOnTouchOutside(false);
return progressDialog;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this instance so it isn't destroyed when MainActivity and
// MainFragment change configuration.
setRetainInstance(true);
backupTask = new BackupTask(this);
backupTask.execute();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (isResumed() && backupTask != null) {
backupTaskDialogFragment = BackupTaskDialogFragment.newInstance();
FragmentManager fm = BackupTaskFragment.this.getFragmentManager();
fm.beginTransaction().add(backupTaskDialogFragment, BACKUP_TASK_DIALOG_FRAGMENT).commitAllowingStateLoss();
}
}
}, 1500);
}
@SuppressLint("NewApi")
public void onPause() {
super.onPause();
android.util.Log.i("CHEOK", "onPause");
Activity activity = this.getActivity();
boolean kill = false;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
if (activity != null && false == activity.isChangingConfigurations()) {
// Stop the thread when home is pressed.
kill = true;
}
} else {
// I have no idea how to perform configuration checking in older API
// Just do nothing, by letting the thread continue to run.
//
// http://stackoverflow.com/questions/15458540/calling-activity-ischangingconfigurations-in-fragment-for-api-level-lesser-than
}
if (kill) {
if (backupTask != null) {
backupTask.cancel(true);
backupTask = null;
}
BackupTaskDialogFragment backupTaskDialogFragment = this.backupTaskDialogFragment;
if (backupTaskDialogFragment != null) {
android.util.Log.i("CHEOK", "onPause dismiss backupTaskDialogFragment");
backupTaskDialogFragment.dismiss();
}
}
}
// This is also called by the AsyncTask.
public void onPostExecute(File file) {
if (isResumed()) {
android.util.Log.i("CHEOK", "onPostExecute isResumed true");
} else {
android.util.Log.i("CHEOK", "onPostExecute isResumed false");
}
backupTask = null;
BackupTaskDialogFragment backupTaskDialogFragment = this.backupTaskDialogFragment;
if (backupTaskDialogFragment != null) {
android.util.Log.i("CHEOK", "onPostExecute dismiss backupTaskDialogFragment");
backupTaskDialogFragment.dismiss();
}
}
public static BackupTaskFragment newInstance() {
return new BackupTaskFragment();
}
private BackupTask backupTask;
private BackupTaskDialogFragment backupTaskDialogFragment = null;
private static final String BACKUP_TASK_DIALOG_FRAGMENT = "BACKUP_TASK_DIALOG_FRAGMENT";
}
public class BackupTask extends AsyncTask<Void, Void, File> {
public BackupTask(BackupTaskFragment backupTaskFragment) {
this.backupTaskFragment = backupTaskFragment;
}
@Override
protected File doInBackground(Void... params) {
android.util.Log.i("CHEOK", "BackupTask sleep for 20 seconds...");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
android.util.Log.i("CHEOK", "BackupTask sleep for 20 seconds done!");
return null;
}
@Override
protected void onPostExecute(File file) {
this.backupTaskFragment.onPostExecute(file);
}
private final BackupTaskFragment backupTaskFragment;
}
正如您所看到的,当BackupTask
完成执行时,它会触发BackupTaskFragment
onPostExecute,以解除BackupTaskDialogFragment
。
但是,在BackupTaskFragment
onPostExecute之前是否有更改配置,解雇BackupTaskDialogFragment
无法正常工作。
知道为什么它不起作用,我们如何解决这个问题?
完整的最小可行代码可以从https://www.dropbox.com/s/dcy856zmp18dhgk/MyApplication.zip?dl=0
下载答案 0 :(得分:1)
当配置发生变化时,this.backupTaskDialogFragment
中的BackupTaskFragment
不再引用当前运行的对话框片段。
而不是
BackupTaskDialogFragment backupTaskDialogFragment = this.backupTaskDialogFragment;
if (backupTaskDialogFragment != null) {
使用
public BackupTaskDialogFragment getBackupTaskDialogFragment() {
Activity activity = getActivity();
if (activity != null) {
FragmentManager fm = activity.getFragmentManager();
return (BackupTaskDialogFragment)fm.findFragmentByTag(BACKUP_TASK_DIALOG_FRAGMENT);
}
return null;
}
...
BackupTaskDialogFragment backupTaskDialogFragment = getBackupTaskDialogFragment();
if (backupTaskDialogFragment != null) {