FragmentManager가 이미 트랜잭션을 실행하고 있습니다. 커밋 후 호출기를 초기화하는 것이 안전합니까?
두 조각을 호스팅하는 활동이 있습니다. 액티비티는 객체를로드하는 동안 로더를 보여주기 시작합니다. 로드 된 객체는 newInstance 메서드를 통해 인수로 두 조각에 전달되고 해당 조각이 연결됩니다.
final FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.container1, Fragment1.newInstance(loadedObject));
trans.replace(R.id.container2, Fragment2.newInstance(loadedObject));
trans.commit();
두 번째 조각에는 android.support.v4.view.ViewPager 및 탭이 포함되어 있습니다. onResume 우리는 다음과 같이 초기화합니다.
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(adapter.getCount()); //the count is always < 4
tabLayout.setupWithViewPager(viewPager);
문제는 Android입니다.
java.lang.IllegalStateException : FragmentManager가 이미 트랜잭션을 실행 중입니다.
이 스택 추적으로 : ( android.support
간결성을 위해 패키지 이름을 제거했습니다)
v4.app.FragmentManagerImpl.execSingleAction (FragmentManager.java:1620) at v4.app.BackStackRecord.commitNowAllowingStateLoss (BackStackRecord.java:637) at v4.app.FragmentPagerAdapter.finishUpdate (FragmentPagerAdapter.java:143) at v4.view.ViewPager .populate (ViewPager.java:1235) at v4.view.ViewPager.populate (ViewPager.java:1083) at v4.view.ViewPager.setOffscreenPageLimit (ViewPager.java:847)
데이터 setOffscreenPageLimit(...);
는 제거 여부를 보여줍니다 . 이 문제를 피할 수있는 다른 방법이 있습니까?
수명주기에서 조각 트랜잭션이 완료되어 호출기를 설정할 때까지 기다릴 수 있습니까?
SDK 24 이상을 대상으로하는 경우 다음을 사용할 수 있습니다.
FragmentTransaction.commitNow()
대신에 commit()
이전 버전을 대상으로하는 경우 다음을 호출 해보십시오.
FragmentManager.executePendingTransactions()
에 대한 호출 후 commit()
간단하게 사용 childFragmentManger()
하기위한 viewpager
내부Fragment
mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
mPager.setAdapter(mPagerAdapter);
두 조각을 빠르게 교체하고 executePendingTransactions ()를 사용할 때이 예외가 발생했습니다. 이것을 부르지 않고 예외는 없었습니다.
내 사건은 어땠어? 나는 조각 A를 열고 onResume () (조건 하에서) 조각을 조각 B로 교체하도록 활동에 요청합니다. 그 시점에서 예외가 발생합니다.
내 해결책은 쿼리를 즉시 실행하는 대신 스레드 대기열 끝에 배치하는 Handler.post (runnable)를 사용하는 것입니다. 이렇게하면 이전 트랜잭션이 완료된 후 새 트랜잭션이 실행됩니다.
그래서 내 솔루션은 다음과 같이 간단했습니다.
Handler uiHandler = new Handler();
uiHandler.post(new Runnable()
{
@Override
public void run()
{
openFragmentB(position);
}
});
누군가 Robolectric> 3.6을 사용하고 ViewPager와 함께 4.0.2 이상을 사용하는 경우 올바른 코드로도 이것을 볼 수 있습니다.
Robolectric에 대한 문제를 추적하는 이 github 문제 에 관련 정보가 있습니다 .
이 답변을 작성할 때 문제가 해결되지 않았으며 알려진 유일한 해결 방법은 일부에서는 작동하는 것처럼 보이지만 나를 위해 작동하지 않는 @Config (sdk = {27})를 사용하거나 해결 방법으로 ViewPagerShadow를 구현하는 것입니다. github에서 참조 된 다소 긴 코드가 포함 된 테스트 패키지 (더 나은 경우 여기에 포함 할 수 있지만 답변으로 충분하지 않을 수 있습니까?) 및 @Config (shadows = {ShadowViewPager.class} 사용)
비슷한 문제가있었습니다.
mainAcitivity 추가 fragmentA.
그런 다음 FragmentA 콜백 mainactivity는 자신을 fragmentB로 대체합니다.
FragmentB로 트랜잭션을 교체하고 커밋 할 때 MainActivity에서 "fragmentmanager가 이미 트랜잭션을 실행 중"예외를 throw합니다.
문제는 실제로 fragmentB에서 발생합니다.
탭 조각을 추가하려면 getfragmentmanager ()가 필요한 조각 B에 TabHost가 있습니다.
Replace getfragmentmanager() by getchildfragmentmanager() in fragmentB solve the issue.
I used/extended my adapter with FragmentStatePagerAdapter
instead of FragmentPagerAdapter
this resolved my issue.
Use FragmentStatePagerAdapter
if the fragments are dynamic and are changing frequently during run-time.
Use FragmentPagerAdapter
if the fragments are static and do NOT change frequently during run-time.
enlightened from this article, https://medium.com/inloopx/adventures-with-fragmentstatepageradapter-4f56a643f8e0
'developer tip' 카테고리의 다른 글
iOS 10 버그 : UICollectionView가 존재하지 않는 인덱스 경로가있는 셀에 대한 레이아웃 속성을 받았습니다. (0) | 2020.11.22 |
---|---|
뒤로 버튼을 누른 조각에서 활동이 비어 있습니다. (0) | 2020.11.22 |
Rails — 텍스트 영역에 줄 바꿈 추가 (0) | 2020.11.22 |
Html.DropDownList-사용 안함 / 읽기 전용 (0) | 2020.11.22 |
Python에서 RGB 색상 튜플을 6 자리 코드로 변환 (0) | 2020.11.22 |