[Android] Fragment 소스 코드 분석 (3) 사무
FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragmentContainer, fragment, "tag");
ft.addToBackStack("<span style="font-family: Arial, Helvetica, sans-serif;">tag</span><span style="font-family: Arial, Helvetica, sans-serif;">");</span>
ft.commitAllowingStateLoss();
이 코드 를 실행 하면 fragment Container 컨트롤 에 Fragment 의 내부 에 컨트롤 을 추가 할 수 있 습 니 다.지난번 에 프 래 그 먼 트 는 상태 기 변경 을 통 해 내부 mView 를 생 성 한다 고 했 습 니 다.from layout. xml 방식 을 사용 하지 않 을 때 Fragment. REATED 상태 에서 container 에 대응 하 는 컨트롤 을 검색 한 다음 mView 를 이 부모 컨트롤 에 추가 합 니 다.그렇다면 이 일 은 또 이 안에서 어떤 역할 을 할 까?
먼저 Manager. beginTransaction 이 방법의 반환 값 을 살 펴 보 겠 습 니 다.
/**
* Start a series of edit operations on the Fragments associated with this
* FragmentManager.
*
* <p>
* Note: A fragment transaction can only be created/committed prior to an
* activity saving its state. If you try to commit a transaction after
* {@link FragmentActivity#onSaveInstanceState
* FragmentActivity.onSaveInstanceState()} (and prior to a following
* {@link FragmentActivity#onStart FragmentActivity.onStart} or
* {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will
* get an error. This is because the framework takes care of saving your
* current fragments in the state, and if changes are made after the state
* is saved then they will be lost.
* </p>
*/
public abstract FragmentTransaction beginTransaction();
Fragment 관리 에서 Fragment Manager 의 실현 클래스 는 Fragment Manager Impl 입 니 다. 물론 이것 도 Android 의 일 관 된 명명 방식 입 니 다.
FragmentManagerImpl.java:
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
Fragment Manager 는 BackStackRecord 라 는 대상 을 되 돌려 업무 처 리 를 완료 합 니 다.안 드 로 이 드 자 체 를 떠 나 우 리 는 업무 에 대한 이 해 는 주로 데이터 베이스 에서 비롯 된다. 즉, 대량의 조작 으로 당신 의 조작 집합 을 기록 한 다음 에 한꺼번에 처리 하여 업무 처리 시의 안전성 과 효율 성 을 확보한다.Fragment Manager 가 사 무 를 보 는 관점 도 대체적으로 일치 합 니 다. BackStackRecord 의 핵심 방법 은 addOp (Op) 입 니 다.
void addOp(Op op) {
if (mHead == null) {
mHead = mTail = op;
} else {
op.prev = mTail;
mTail.next = op;
mTail = op;
}
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
mNumOp++;
}
우 리 는 BackStackRecord 의 조작 처리 조직 에 대해 '교체 기' 모델 을 사용 하고 모든 조작 이 Op 대상 으로 기록 되 고 '비망록' 모델 로 볼 수 있다 는 것 을 보 았 다.추가 작업 의 입구:
public FragmentTransaction add(Fragment fragment, String tag) {
doAddOp(0, fragment, tag, OP_ADD);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
doAddOp(containerViewId, fragment, tag, OP_ADD);
return this;
}
"Builder" 방식 으로 조직 합 니 다.글 을 시작 할 때 저 는 Fragment 의 사무 관 리 는 비교적 훌륭 한 코드 라 고 언급 했 습 니 다. 단순 한 사 무 는 적어도 세 가지 모델 로 조직 되 었 고 조직 하면 전혀 느낌 이 없습니다.물론 프 래 그 먼 트 가 우리 에 게 준 서 프 라 이 즈 는 여기에 그 치지 않 는 다.우 리 는 위의 코드 세 션 을 통 해 알 수 있 듯 이 실제 적 으로 사무 류 BackStackRecord 를 통 해 Op 대상 이 실제 적 으로 BackStackRecord 의 속성 을 복사 하고 있 기 때문에 모든 Op 안의 데 이 터 를 분석 할 때 BackStackRecord 의 속성 으로 직접 매 핑 할 수 있다.
int mNumOp;//Op
int mEnterAnim;//
int mExitAnim;//
int mPopEnterAnim;//
int mPopExitAnim;//
int mTransition;//
int mTransitionStyle;
boolean mAddToBackStack;// BackStack
Op 자 체 는 Command 모드 에 속 합 니 다. Command 목록 은 다음 과 같 습 니 다.
static final int OP_NULL = 0;
static final int OP_ADD = 1;
static final int OP_REPLACE = 2;
static final int OP_REMOVE = 3;
static final int OP_HIDE = 4;
static final int OP_SHOW = 5;
static final int OP_DETACH = 6;
static final int OP_ATTACH = 7;
아마 너 도 알 아 차 렸 을 거 야. 맞 아, Op 의 속성 은 Command 로 서 의 조작 수 야.BackStackRecord 에서 Commit 를 진행 한 후, BackStackRecord 는 자신 을 Fragment Manager Impl 의 명령 대기 열 에 포함 시 켜 처리한다.모든 처리 부 는 각자 의 Op 작업 을 처리 하 는 데 사용 된다.코드 를 살 펴 보 겠 습 니 다.
BackStackRecord.java:
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex(this);
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
BackStackRecord 는 제출 할 때 자신 을 mManager 의 Action 대기 열 에 제출 합 니 다.이러한 Action 대기 열 처 리 는 임의의 스 레 드 에서 진행 할 수 있 습 니 다.
FragmentManager.java:
public void enqueueAction(Runnable action, boolean allowStateLoss) {
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mActivity == null) {
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<Runnable>();
}
mPendingActions.add(action);
if (mPendingActions.size() == 1) {
mActivity.mHandler.removeCallbacks(mExecCommit);
mActivity.mHandler.post(mExecCommit);
}
}
}
우 리 는 실제 Action 이 mExec Commit 명령 에 의 해 실 행 된 것 을 보 았 습 니 다. 그것 은 당신 이 제출 한 BackStack Record 의 run 방법 을 되 돌려 줍 니 다.
BackStackRecord.java:
Op op = mHead;
while (op != null) {
...
}
우 리 는 명령 이 교체 기 방식 으로 순환 되 고 있 는 것 을 보 았 다.서로 다른 명령 은 Fragment 에 대해 서로 다른 상태 변경 작업 을 할 것 입 니 다. 간단 한 예 를 들 어:
Op.java:
case OP_ADD: {
Fragment f = op.fragment;
f.mNextAnim = op.enterAnim;
mManager.addFragment(f, false);
} break;
Fragment 를 추가 해 야 할 때 Op 는 Fragment Manager 의 addFragment 방법 을 호출 합 니 다.
FragmentManager.java:
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (mAdded == null) {
mAdded = new ArrayList<Fragment>();
}
makeActive(fragment);
if (!fragment.mDetached) {
if (mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: "
+ fragment);
}
mAdded.add(fragment);
fragment.mAdded = true;
fragment.mRemoving = false;
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
if (moveToStateNow) {
moveToState(fragment);
}
}
}
Fragment Manager 는 이 를 자신의 mAdded 대기 열 에 먼저 추가 한 다음 moveToState 방법 으로 Fragment 상 태 를 바 꾸 어 상태의 일치 성 을 확보 합 니 다.이 부분 은 바로 우리 가 지난 부분 에서 말 한 내용 이 므 로 우 리 는 더 이상 군말 하지 않 는 다.이렇게 해서 Fragment 는 이런 우아 한 방식 으로 업무 처 리 를 실현 했다.다음 편 에 서 는 프 래 그 먼 트 가 Stack 관리 에 관 한 일부 소스 코드 를 들 려 드 리 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.