android – 循环后,片段事务给出了IllegalStateException

android – 循环后,片段事务给出了IllegalStateException,第1张

概述我有Fragments和BroadcastManager的问题. 在我的应用程序中,我切换到一个主要活动并使用新的NavigationDrawer.所有内容都包含在片段中. One Fragment(搜索用户)包含两个选项卡(按名称搜索,按标准搜索),使用Android设计网站中的导航模式“横向导航”:它有一个带有FragmentStatePagerAdapter的ViewPager. | Ma 我有Fragments和broadcastManager的问题.
在我的应用程序中,我切换到一个主要活动并使用新的NavigationDrawer.所有内容都包含在片段中.

One Fragment(搜索用户)包含两个选项卡(按名称搜索,按标准搜索),使用Android设计网站中的导航模式“横向导航”:它有一个带有FragmentStatePagerAdapter的VIEwPager.

|  Main Activity  |    |  Main Activity  |-------------------    -------------------| Search Fragment |    | Search Fragment || >Tab 1< | Tab 2 |    | Tab 1 | >Tab 2< ||    VIEw Pager   |    |    VIEw Pager   ||   Fragment 1    |    |   Fragment 2    |

我希望两个选项卡都使用相同的 *** 作栏(选项)菜单:搜索 *** 作.
但只有活跃的片段才会对它做出反应.

我尝试过不同的方法,最烦人的是我无法直接从视图分页器中获取当前片段(不依赖于非API实现细节).

途径

我现在使用Localbroadcast来通知片段已经点击了搜索.每个片段在onResume中注册一个小的Wrapper-Receiver(并在onPause中删除它),它将onReceive转发给片段本身(下面显示的方法).
我重写setMenuVisibility,它是FragmentStatePagerAdpater在Fragments上调用的回调,以了解哪个是活动片段.
只有菜单集可见的片段才会对广播做出反应.

Actionbar Tab -> VIEwPager -> VIEwPagerAdapter -> Fragment.setMenuVisibilityActionbar Menu Action -> broadcast ->  ... -> broadcastReceiver -> Fragments

两个片段都会触发片段事务以显示搜索结果并将其添加到后台堆栈.

问题
片段事务通常起作用,但是当我旋转设备然后按搜索时,我得到一个IllegalStateException(在onSaveInstanceState之后无法提交).

@OverrIDe    public voID onReceive(Context context,Intent intent) {        if (m_menuVisible) {            final String s = ((TextVIEw) getVIEw().findVIEwByID(R.ID.search_text)).getText().toString();            SearchResultsFragment f = new UserSearchResultsFragment();            Bundle b = new Bundle();            b.putString(SearchResultsFragment.EXTRA_SEARCHname,s);            f.setArguments(b);            FragmentTransaction transaction = getSherlockActivity().getSupportFragmentManager().beginTransaction();            transaction.replace(R.ID.fragment_container_frame,f).addToBackStack(null).commit(); // <<< CRASH        }    }

我试图将提交更改为commitAllowingStateLoss,但随后我得到一个IllegalStateException,其中“Activity已被销毁”.

你知道这里出了什么问题吗?我不知所措……

附加代码:

MainActivitIEs onCreate(基于NavigationDrawer示例)和selectItem

@OverrIDeprotected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    requestwindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);    setContentVIEw(R.layout.fragment_container_layout);    setupDrawer(); // Sets up the drawer layout,adapter,etc.    if (savedInstanceState == null) {        selectItem(0); // Selects and adds the fragment(s) for the position    }    // Other setup stuff}private voID selectItem(int position) {        // update the main content by replacing fragments        Fragment f = null;        switch (position) {            case 0:                f = ...                break;            case 1:                ...            default:                throw new IllegalArgumentException("Could not find right fragment");        }        f.setRetainInstance(true);        m_drawerList.setItemChecked(position,true);        setTitle(mDrawerTitles.get(position).TitleRes);        // HIDe any progress bar that might be visible in the actionbar        setProgressbarIndeterminateVisibility(false);        // When we select something from the navigation drawer,the back stack is discarded        final FragmentManager fm = getSupportFragmentManager();        fm.popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);        fm.beginTransaction().replace(R.ID.fragment_container_frame,f).commit();        // update selected item and Title,then close the drawer        m_drawerLayout.closeDrawer(GravityCompat.START);    }

故障选项卡片段中的FragmentStatePagerAdapter:

protected class TabPagerAdapter extends FragmentStatePagerAdapter {        private List<String> m_fragmentTags = new ArrayList<String>();        public TabPagerAdapter(FragmentManager fm) {            super(fm);        }        public voID addFragments(List<String> List) {            VIEwPager pager = (VIEwPager) getVIEw().findVIEwByID(R.ID.vIEwpager);            startUpdate(pager);            for (String tag : List) {                m_fragmentTags.add(tag);            }            finishUpdate(pager);            notifyDataSetChanged();        }        public voID addFragment(String tag) {            addFragments(Collections.singletonList(tag));        }        @OverrIDe        public Fragment getItem(int pos) {            // CreateFragmentForTag: RetrIEves the classes,instantiates the fragment            // Does not do retainInstance or any transaction there.            return createFragmentForTag(m_fragmentTags.get(pos));        }        @OverrIDe        public int getCount() {            return m_fragmentTags.size();        }}

该项目的精简版仅包含必需品,发布于https://docs.google.com/file/d/0ByjUMh5UybW7cnB4a0NQeUlYM0E/edit?usp=sharing

重现如下:启动,您会看到两个选项卡.选择其中一个并单击Actionbar中的搜索 – >片段交易有效.使用返回键,旋转设备并重复 – >崩溃!
[在赏金结束或发现错误后,该文件可能无法访问.]

编辑:
(1)澄清onReceive生活在片段的上下文中
(2)增加了主要活动的代码

解决方法 将我的评论转移到这里的答案,并扩展它.

第一个线索是你只在旋转后崩溃,并且你有setRetainInstance(true).首先,尝试将其设置为false.即使这可以防止崩溃,你仍然需要谨慎.它可能指向一些其他错误,你现在通过不保留你的片段实例来掩盖它.

有没有特别的原因你首先设置了setRetainInstance(true)?

至于为什么你开始看到崩溃,我仍然不能指出这个问题.我怀疑旋转后调用了错误的onReceive – 但这只是在黑暗中拍摄的.

如果您可以创建应用程序的框架并在某处发布代码,我可以查看它.我知道你已经总结了如何“转发”onReceive(),但如果做得不对,就有可能在那里引入BUG.

如果这是不可能的,这就是我的建议 – 将日志语句放在Activity,Fragments和onReceive()的主要生命周期方法中.这会告诉你发生的确切顺序.

总结

以上是内存溢出为你收集整理的android – 循环后,片段事务给出了IllegalStateException全部内容,希望文章能够帮你解决android – 循环后,片段事务给出了IllegalStateException所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1129259.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存