Android: setReatinInstance(true) 不工作

Android: setReatinInstance(true) not working

我试图在配置更改时保留片段,但即使在使用 setRetainInstace(true) 之后,onDestroy() 也会在屏幕旋转时被调用

这是我的片段代码:

public class HelloMoonFragment extends Fragment{

    private Button mPlay;
    private Button mStop;
    private Button mPause;
    private AudioPlayer mPlayer = new AudioPlayer();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_hello_moon, null);

        mPlay = (Button) v.findViewById(R.id.hellomoon_playButton);
        mPlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mPlayer.play(view.getContext());
            }
        });

        mStop = (Button) v.findViewById(R.id.hellomoon_stopButton);
        mStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mPlayer.stop();
            }
        });

        mPause = (Button) v.findViewById(R.id.hellomoon_pauseButton);
        mPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    mPlayer.playpause();
                }catch (IllegalStateException | NullPointerException ex){
                    mPlayer.play(getActivity());
                }
            }
        });

        return v;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Toast.makeText(getActivity(), "Ikkkkkkkkkkkkkkkkkk", Toast.LENGTH_SHORT);
        Log.i("HEYEE", "NOOO");
        mPlayer.stop();
    }
}

这是我的布局 xml 文件:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/helloMoonFragment"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:name="com.github.domain.hellomoon.HelloMoonFragment">

</fragment>

为什么每次旋转都会调用 onDestroy()?

onDestroy() 不会被调用,但在您的示例中,它是:

@Override
    public void onDestroyView() {
        super.onDestroyView();
        Toast.makeText(getActivity(), "Ikkkkkkkkkkkkkkkkkk", Toast.LENGTH_SHORT);
        Log.i("HEYEE", "NOOO");
        mPlayer.stop();
    }

OnDestroy!=onDestroyView

onDestroy() 将不会被调用(但 onDetach() 仍然会被调用,因为片段正在从其当前 activity 分离)。

onDestroyView 当先前由 onCreateView(LayoutInflater, ViewGroup, Bundle) 创建的视图与片段分离时调用

这是设计好的。无论 setRetainInstance() 标志如何,都会在配置更改时调用 onDestroyView()。但是,onDestroy() 不会被调用。

原因是托管片段的 Activity 可能仍会被销毁并重新创建 - 因此,您 Fragment 中的任何 View 引用都将仍然持有对那个现已死亡 Activity 的引用。因此,预期的行为是任何实例状态、运行 任务等都可以在配置更改期间正常继续;但是,您仍然有责任释放您的 View 引用并在 onCreateView().

中重新创建它们