阻止 android 重新创建特定 Fragment 的新实例

Prevent android from recreating new instance of a specific Fragment

提问人:Peppo 10 提问时间:11/3/2023 更新时间:11/17/2023 访问量:51

问:

我有这个结构:

MainActivity -> ProfileFragment -> ListFragment

其中“->”是FragmentTransaction.add(....)

我的问题是,如果我在实现中“自己”完成,我是否需要 android 来重新加载子片段的旧实例(例如在旋转设备时)?

因为当 android 重新创建第一个 Activity 并到达该方法时,Activity 本身会重新创建 ProfileFragment 等等......onStart()

我也尝试了一些测试,结果如下Log

首次创作:

2023-11-02 18:54:59.141 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ProfileFragment instance created from MainActivity
2023-11-02 18:54:59.161 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ProfileFragment: ProfileFragment{4eef489} (7ad3c3ad-8de4-4205-bc33-5e803c9c0f36 id=0x7f090101) onCreateView()
2023-11-02 18:54:59.170 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ListFragment instance created from ProfileFragment
2023-11-02 18:54:59.171 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ListFragment: ListFragment{74e1ea1} (03980350-9ab1-4857-a7f3-d71560f949cf id=0x7f0901bb) onCreateView()

旋转后:

2023-11-02 18:51:46.127 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ProfileFragment instance created from android
2023-11-02 18:51:46.128 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ListFragment instance created from android
2023-11-02 18:51:46.164 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ProfileFragment instance created from MainActivity
2023-11-02 18:51:46.167 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ProfileFragment: ProfileFragment{9373e8c} (a5b6a134-359d-46bc-a487-270f4e970b41 id=0x7f090101) onCreateView()
2023-11-02 18:51:46.410 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ListFragment: ListFragment{fb9c6ab} (a78556b1-fe09-4b21-b40b-c3fc21fc9728 id=0x7f0901bb) onCreateView()
2023-11-02 18:51:46.416 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ProfileFragment: ProfileFragment{5d59c38} (063fb353-0129-4a4a-9db3-c72578aea443 id=0x7f090101) onCreateView()
2023-11-02 18:51:46.427 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ListFragment instance created from ProfileFragment
2023-11-02 18:51:46.428 16908-16908 Rotation Test           it.uniba.dib.sms222334               D  ListFragment: ListFragment{aad4157} (23af9cd1-15e2-4ddc-aa59-c138b79a5d8e id=0x7f0901bb) onCreateView()

为了完整起见,我还放置了这种情况的构造函数

ListFragment:

public ListFragment() {
        Log.d("Rotation Test","ListFragment instance created from android");
        currentUser=SessionManager.getInstance().getCurrentUser();

        currentUserRole=currentUser.getRole();
    }

    public ListFragment(String overrideParams){

    }


    public static ListFragment newInstanceProfile(ProfileFragment.Tab tabPosition, ProfileFragment.Type profileType, User profile) {
        ListFragment myFragment = new ListFragment("justForOverrideTheConstructor");
        Bundle args = new Bundle();
        args.putInt("tab_position", tabPosition.tabPosition.ordinal());
        args.putInt("profile_type", profileType.ordinal());
        args.putParcelable("profileData", profile);
        myFragment.setArguments(args);

        Log.d("Rotation Test","ListFragment instance created from ProfileFragment");

        return myFragment;
    }

ProfileFragment:

public ProfileFragment(){
        Log.d("Rotation Test","ProfileFragment instance created from android");
    }

    private ProfileFragment(String overrideParams){

    }

    public static ProfileFragment newInstance(User profile) {
        ProfileFragment myFragment = new ProfileFragment("justForOverrideTheConstructor");

        Bundle args = new Bundle();
        args.putParcelable("profileData", profile);
        myFragment.setArguments(args);

        Log.d("Rotation Test","ProfileFragment instance created from MainActivity");

        return myFragment;
    }

因此,当我旋转设备时,如您所见,我有两个片段的实例,这不是我想要的结果。

我看到了一些解决方案,但这是一个很好的解决方案吗?我知道它是与非 UI-Fragments 一起使用的东西,否则它会生成 memoryLeak。setRetainInstance(true)

片段 android-activity fragmenttransaction onsaveinstancestate

评论


答:

0赞 Rob 11/17/2023 #1

您可以使用这两个回调来处理它,

override fun onSaveInstanceState(bundle: Bundle){
  // save the data you need here by just putting it into bundle
}

override fun onRestoreInstanceState(bundle: Bundle){
  // retrieve the data you need here by just getting it from bundle
}

因此,您不会使您的片段不可销毁(恕我直言,这是不可能的,因为您的活动会重新创建),但您可以保存它们拥有的 UI 状态并正确恢复它