IT이야기

새로운 FragmentTransaction commitNow()는 내부 작동 원리

cyworld 2021. 10. 7. 21:04
반응형

새로운 FragmentTransaction commitNow()는 내부적으로 어떻게 작동합니까?


Android N 및 지원 라이브러리 버전 24에 추가된 새로운 commitNow() 메서드에는 제한적이고 약간 혼란스러운 설명서가 있습니다.

이 트랜잭션을 동기적으로 커밋합니다. 추가된 프래그먼트는 초기화되어 호스트의 수명 주기 상태로 완전히 전환되며 제거된 프래그먼트는 이 호출이 반환되기 전에 그에 따라 해체됩니다. 이러한 방식으로 트랜잭션을 커밋하면 조각이 호스트의 수명 주기 상태를 모니터링하는 캡슐화된 전용 구성 요소로 추가되는 동시에 해당 조각이 완전히 초기화되고 준비될 때 더 확실한 순서 지정 보장을 제공할 수 있습니다. 보기를 관리하는 프래그먼트에는 해당 보기가 생성되고 연결됩니다.

commitNow를 호출하는 것은 FragmentManager.executePendingTransactions() 다음에 오는 commit()을 호출하는 것보다 선호됩니다. 후자는 원하는 동작이든 아니든 현재 보류 중인 모든 트랜잭션을 커밋하려고 시도하는 부작용이 있기 때문입니다.

이러한 방식으로 커밋된 트랜잭션은 FragmentManager의 백 스택에 추가되지 않을 수 있습니다. 그렇게 하면 다른 비동기적으로 커밋된 트랜잭션에 대해 예상되는 다른 순서 보장이 깨질 수 있기 때문입니다. 트랜잭션이 이전에 addToBackStack(String) 으로 백 스택에 추가되도록 요청한 경우 이 메서드는 IllegalStateException을 throw합니다 .

트랜잭션은 상태를 저장하는 포함 활동 이전에 이 메서드로만 커밋할 수 있습니다. 그 이후에 커밋을 시도하면 예외가 발생합니다. 활동을 상태에서 복원해야 하는 경우 커밋 후 상태가 손실될 수 있기 때문입니다. 커밋을 잃어도 괜찮은 상황에 대해서는 commitAllowingStateLoss()를 참조하십시오.

헷갈린다고 생각되는 부분을 굵은 글씨로 표시했습니다.

따라서 내 주요 관심사/질문은 다음과 같습니다.

1 - 추가할 수 없습니까? IllegalStateException이 발생한다고 되어 있는데 추가되지 않을까요?

2 - 백스택에 프래그먼트를 추가하려면 이것을 사용할 수 없다는 사실을 인정합니다. 그것이 말하지 않는 것은이 예외가 발생한다는 것입니다.

java.lang.IllegalStateException: This transaction is already being added to the back stack

!!!!????

그래서 addToBackStack(String)내부적으로 나를 위해 부르고 있기 때문에 나 자신을 부를 수 없습니까? 미안하지만... 뭐? 왜요? 백스택에 추가하지 않으려면 어떻게 해야 합니까? 그리고 나중에 백스택에서 해당 조각을 사용하려고 하지만 추가되지 않을 수도 있기 때문에 나중에 존재하지 않으면 어떻게 됩니까?

내가 사용 commitAllowingStateLoss()하고 있었다면 이것이 예상된 것 같지만, commitNowAllowingStateLoss()그것도 존재 한다는 것을 알았습니다. 그래서... 어떤 종류의 논리를 따르나요?

TL;DR

commitNow()는 백스택과 관련하여 내부적으로 어떻게 작동합니까?


우리가 이와 같은 질문에 직면했을 때 Android 소스 코드가 오픈 소스라는 것은 좋은 일입니다!

답변

여기 에서 BackStackRecord 소스를 살펴보겠습니다.

@Override
public void commitNow() {
    disallowAddToBackStack();
    mManager.execSingleAction(this, false);
}

@Override
public FragmentTransaction disallowAddToBackStack() {
    if (mAddToBackStack) {
        throw new IllegalStateException(
                "This transaction is already being added to the back stack");
    }
    mAllowAddToBackStack = false;
    return this;
}

그리고 mAddToBackStack당신이 호출하는 경우 true로 설정됩니다 addToBackStack트랜잭션에.

So to answer your question, no addToBackStack isn't called internally when you call commitNow(), It's the exception message that ambigous. I think it should say You're not allowed to add to backstack when using commitNow() instead the current message.

Bonus:

If we dig deeper into FragmentManager source code here, commitNow() actually doing almost same thing as executePendingTransactions() like written above, but instead executing all previously committed transaction, commitNow() will only commit that transaction.

I think that's the main reason why commitNow() isn't allowing addition to the backstack since it cannot guarantee there aren't any other pending transaction. If commitNow() can add to the backstack, there is a possibility that we can break our backstack sequence that will leading into unexpected thing.

ReferenceURL : https://stackoverflow.com/questions/38566628/how-is-the-new-fragmenttransaction-commitnow-working-internally

반응형