【问题标题】:FragmentTransaction working only in portrait modeFragmentTransaction 仅在纵向模式下工作
【发布时间】:2014-07-11 13:42:34
【问题描述】:

我的 Android 代码有一个非常奇怪的行为。

实际问题在代码之后。

我想做的是有一个应用程序,它只能在手机上的纵向模式和平板电脑上的纵向和横向模式下工作。为此,我在不同的文件夹中创建了三个 bool.xml 文件。这个在文件夹值中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">true</bool>
</resources>

在我放的 values-xlarge 和 values-sw600dp 中

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="portrait_only">false</bool>
</resources>

项目中唯一的活动加载,在启动时通过附加一个 SplashScreenFragment 来启动一个初始屏幕。这里是活动

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getResources().getBoolean(R.bool.portrait_only)) 
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    if (getSupportActionBar() != null)
        getSupportActionBar().hide();
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
        .add(R.id.container, new SplashScreenFragment()).commit();
    }
}
}

片段本身只是加载一个布局并启动一个更改片段的 TimerTask。在这里

public class SplashScreenFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

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

        Timer splashScreenTimer = new Timer();
        splashScreenTimer.schedule(new SplashScreenTimerTask(getActivity()), 2000);

        return rootView;
    }

    private class SplashScreenTimerTask extends TimerTask {
        private FragmentActivity activity;

        public SplashScreenTimerTask(FragmentActivity activity) {
            this.activity = activity;
        }

        @Override
        public void run() {
            FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.container, new FragmentMain());
            transaction.commit();
        }

    }

}

现在,如果我在手机上以纵向模式启动应用程序,一切都可以完美运行,而如果我在手机以横向模式启动应用程序,那么第一个片段会完美加载,但是当行

transaction.commit();

执行后,应用程序崩溃并在 logcat 中出现以下错误

E/AndroidRuntime(17433): FATAL EXCEPTION: Timer-0
E/AndroidRuntime(17433): Process: it.assottica.android, PID: 17433
E/AndroidRuntime(17433): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
E/AndroidRuntime(17433):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1354)
E/AndroidRuntime(17433):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1372)
E/AndroidRuntime(17433):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
E/AndroidRuntime(17433):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
E/AndroidRuntime(17433):    at it.assottica.android.fragments.SplashScreenFragment$SplashScreenTimerTask.run(SplashScreenFragment.java:40)
E/AndroidRuntime(17433):    at java.util.Timer$TimerImpl.run(Timer.java:284)

有人知道为什么会发生这种情况以及如何解决吗?但是,最重要的是,如果我在手机上以横向或纵向模式启动应用程序,为什么一切正常?

【问题讨论】:

  • @the-guy-with-the-hat,感谢编辑,虽然我不明白为什么我不能提前感谢某人。作为一名编辑,我有一个问题要问你:既然我已经解决了自己的问题,我可以将我的答案标记为正确还是违反某些 stackoverflow 的政策?
  • 是的。您也可以accept your own answer,但您必须等待 48 小时才能这样做。 stackoverflow.com/help/self-answer
  • 查看this编辑问题时是否应该删除“绒毛”的回答?,特别是在它说“与问题/帖子无关的任何内容都是噪音和应该被删除。这包括......签名,'谢谢'......“是的,你可以而且应该接受你自己的答案。

标签: java android android-fragments android-appcompat


【解决方案1】:


我通过深入追踪 Activity 和 Fragment 的 onPause、onStop 中的哪些方法实际执行了自己的问题。

和我想的不一样,当我在横向模式下开始用手机定向时,Activity和Fragment经历了以下过程:onCreateView -> onPause -> onStop -> onDestroy -> onCreateView,这正是当您以某个方向启动 Activity 然后更改屏幕方向时,会发生相同的过程。这导致 Fragment 被启动,然后被销毁,然后重新启动,因此在第一次启动时创建的计时器,试图获取实际不存在的活动的支持片段管理器或在执行 onSaveInstanceState 后执行事务。

我通过在 Fragment 的 onDestroy() 方法中取消定时器来解决。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 2016-12-13
    相关资源
    最近更新 更多