在我的活动中,我经常使用这个成语:
@Override
public void onDestroy() {
super.onDestroy();
if (isFinishing() != true) return;
// do some final cleanup since we're going away for good
}
Fragment有一个onDestroy()
方法,但是与isFinishing()
等价的是什么?我应该从片段的onDestroy()
中检查getActivity().isFinishing()
吗?
编辑添加:
以下是我在各种情况下得到的回调(按顺序),以及getActivity()
是否返回null或非null,如果非null, getActivity().isFinishing()
的值:
场景#1:DialogFragment
显示,用户点击后退按钮(即需要释放引用):
onDismiss(): activity = non-null, finishing = false
onDestroy(): activity = non-null, finishing = false
场景#2:DialogFragment
显示并且父活动完成(即需要释放引用):
onDestroy(): activity = non-null, finishing = true
onDismiss(): activity = null, finishing = n/a
场景#3:DialogFragment
显示,操作系统暂时破坏父活动(即不应该释放引用):
onDestroy(): activity = non-null, finishing = false
onDismiss(): activity = null, finishing = n/a
fragment有一个叫做isRemoving()
的方法,当fragment被从Activity中移除时,这个方法是正确的:
返回true,如果此片段当前正在从其活动中删除。这不是它的活动是否结束,而是它是否处于从其活动中移除的过程中。
谢谢大家的帮助。我最终将这些添加到我的DialogFragment:
private void doReleaseReferences() {
// release the stuff
}
@Override
public void onDestroy() {
super.onDestroy();
if (getActivity().isFinishing())
doReleaseReferences();
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (getActivity() != null)
doReleaseReferences();
}
基于我添加到原始问题中的回调行为,我认为这符合我的目的。当返回按钮被按下或父活动完成时,引用被释放;当父活动被操作系统销毁并打算稍后恢复时,它们不会被释放。
如果你想在每个基础上清理片段引用,你可以使用这个帮助方法来替换片段
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
if (isFinishing()) {
notifyStackedFragmentsFinishing();
}
super.onDestroy();
}
protected void changeFragment(Fragment fragment) {
notifyStackedFragmentsFinishing();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment, fragment)
.commit();
}
private void notifyStackedFragmentsFinishing() {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null && !fragments.isEmpty()) {
for (Fragment fragment : fragments) {
((BaseFragment) fragment).releaseOnFinishing();
}
}
}
}
现在你可以从BaseActivity扩展所有的activity,从BaseFragment扩展所有的fragment。此外,如果你堆叠片段,你可能应该扩展更多,即onBackPressed()我认为这个kotlin扩展函数可以做到这一点。至少在你使用导航框架
的时候fun Fragment.isFinishing(): Boolean {
val name = this.javaClass.name
val thisEntry = findNavController().backQueue.find {
val destination = it.destination
destination is FragmentNavigator.Destination && destination.className == name
}
return thisEntry == null
}