Fragment 必须是公共静态类才能从实例状态正确重新创建 [英] Fragment must be a public static class to be properly recreated from instance state

本文介绍了Fragment 必须是公共静态类才能从实例状态正确重新创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新到最新的支持库后,

After updating to the latest support repository,

compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
compile 'com.android.support:percent:24.2.0'
compile 'com.android.support:recyclerview-v7:24.2.0'

我遇到了奇怪的异常.

java.lang.IllegalStateException: Fragment null must be a public static class to be  properly recreated from instance state.
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:435)
at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:414)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:154)
at com.androidapp.base.BaseActivity.showDialogFragment(BaseActivity.java:78)
at com.androidapp.MainActivity.showNewDialog(MainActivity.java:304)
at com.androidapp.MainActivity$6.onClick(MainActivity.java:228)

在我的 BaseActivity 类中,我创建了一个可重复使用的片段,它可以在扩展 BaseActivty

In my BaseActivity class, I've created a re-usable fragment which can be used in activity class that extends the BaseActivty

public void showDialogFragment(DialogFragment newFragment) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
        if (prev != null) {
            ft.remove(prev);
        }
        ft.addToBackStack("dialog");
        newFragment.show(ft, "dialog");
    }

回到 MainActivty 我已经使用过这样的片段,

Back to the MainActivty I've used the fragment like this,

public class MainActivity extends BaseActivity {

    @SuppressLint("ValidFragment")
        public void showNewDialog(int type, String title, String message) {
            final DialogNew dialog = new DialogNew() {
                @Override
                public void success(boolean isLandscape) {
                    .......
                }

                @Override
                public void cancel() {

                }
            };
            dialog.setArgs(title, message);
            super.showDialogFragment(dialog);
        }
}

DialogNew 类在下面,

public abstract class DialogNew extends DialogFragment {

    private View rootView;

    private String title;
    private String message;

    public void setArgs(String title, String message) {
        Bundle args = new Bundle();
        args.putString("title", title);
        args.putString("message", message);
        setArguments(args);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE, 0);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        rootView = inflater.inflate(R.layout.fragment_new_dialog, container, false);

        init();
        setListeners();

        return rootView;
    }

    public abstract void success(boolean isLandscape);

    public abstract void cancel();
}

PS:相同的代码适用于较旧的支持存储库.

PS: The same code works with older support repository.

推荐答案

这个错误并不是特别奇怪.如果您之前没有收到此错误,很奇怪.

The error is not especially weird. If you were not getting this error before, that was weird.

Android 销毁并重新创建片段作为配置更改的一部分(例如,屏幕旋转)以及在需要时作为重建任务的一部分(例如,用户切换到另一个应用程序,您的应用程序进程在后台终止时,然后用户尝试返回到您的应用程序,全部在 30 分钟左右).Android 无法重新创建 DialogNew 的匿名子类.

Android destroys and recreates fragments as part of a configuration change (e.g., screen rotation) and as part of rebuilding a task if needed (e.g., user switches to another app, your app's process is terminated while it is in the background, then the user tries to return to your app, all within 30 minutes or so). Android has no means of recreating an anonymous subclass of DialogNew.

因此,创建一个扩展 DialogNew 的常规 public Java 类(或一个 public static 嵌套类)并拥有您的业务逻辑,替换您目前使用的 DialogNew 的匿名子类.

So, make a regular public Java class (or a public static nested class) that extends DialogNew and has your business logic, replacing the anonymous subclass of DialogNew that you are using presently.

这篇关于Fragment 必须是公共静态类才能从实例状态正确重新创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆