DataBinding/ViewBinding은 NonNull 또는 lateinit 관리이므로 무심코 보기를 보는 것을 방지하는 것이 좋습니다

6892 단어 AndroidDataBinding
Fragment를 사용하여 구현할 때 View를 탐색하려고 하면 화면이 붕괴될 수 있습니다.

예:

  • Fragment를 참조하지만 Fragment의 라이프 사이클은 Destroyed
  • 왠지 모르게 무의식중에 호출OnScrollChangedListener
  • onActivityCreated 또는 onResume 시간에 설정된 Runnable 처리
  • 하계.
    onDestroyViewonPause 청중을 잘라도 발매 후 몇 건이 띄엄띄엄 올라가는지 모르겠다.

    화면이 폐기되었는지 확인하기가 매우 어렵다


    이는 LiveDataCoroutine KTX 등 확장 모듈도 충실하고 수명주기와 관련된 처리가 가능하기 때문에 제품에 사용할 경우 메모리 유출과 의도하지 않은View의 참조로 인한 붕괴가 발생하기 어렵기 때문이다.그럼에도 불구하고 역사가 유구한 제품 중 낡은 코드가 즐비한 상황에서 모든 서비스가 추세에 따라 실시될 수 있는 것은 아니다.
    그럼에도 DataBinding 아닌지 null 검사는 비현실적이며, lateinit 화면 폐기 후 검사도 어렵다.
    Butter Knife가 전성할 때 Fragment 내에서 Unbinder 클래스를 정의했기 때문에 Nullable 에서 화면이 폐기되었는지 판단한다.

    isViewDestroyed 플래그 만들기


    각 청중의 리셋에서 우리는 아래와 같이 조기 리셋을 진행하기로 결정했다.
    나는 Fragment 클래스에서 좋은 변수를 발견했기 때문에 그것을 사용해 보았다.
    FragmentExt.kt
    fun Fragment.isViewDestroyed(): Boolean {
        return viewLifecycleOwnerLiveData.value == null
    }
    
    Unbinderがnullかどうか는 LiveData 관리viewLifecycleOwnerLiveData로 onCreateView가 onDestroyView의 역할 영역에서 value를 얻을 수 있는 것 같습니다.반면 onDestroyView에서 참조하는 경우 value는 LifecycleOwner입니다.
    Fragment.java
    /**
         * Get a {@link LifecycleOwner} that represents the {@link #getView() Fragment's View}
         * lifecycle. In most cases, this mirrors the lifecycle of the Fragment itself, but in cases
         * of {@link FragmentTransaction#detach(Fragment) detached} Fragments, the lifecycle of the
         * Fragment can be considerably longer than the lifecycle of the View itself.
         * <p>
         * Namely, the lifecycle of the Fragment's View is:
         * <ol>
         * <li>{@link Lifecycle.Event#ON_CREATE created} after {@link #onViewStateRestored(Bundle)}</li>
         * <li>{@link Lifecycle.Event#ON_START started} after {@link #onStart()}</li>
         * <li>{@link Lifecycle.Event#ON_RESUME resumed} after {@link #onResume()}</li>
         * <li>{@link Lifecycle.Event#ON_PAUSE paused} before {@link #onPause()}</li>
         * <li>{@link Lifecycle.Event#ON_STOP stopped} before {@link #onStop()}</li>
         * <li>{@link Lifecycle.Event#ON_DESTROY destroyed} before {@link #onDestroyView()}</li>
         * </ol>
         *
         * The first method where it is safe to access the view lifecycle is
         * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} under the condition that you must
         * return a non-null view (an IllegalStateException will be thrown if you access the view
         * lifecycle but don't return a non-null view).
         * <p>The view lifecycle remains valid through the call to {@link #onDestroyView()}, after which
         * {@link #getView()} will return null, the view lifecycle will be destroyed, and this method
         * will throw an IllegalStateException. Consider using
         * {@link #getViewLifecycleOwnerLiveData()} or {@link FragmentTransaction#runOnCommit(Runnable)}
         * to receive a callback for when the Fragment's view lifecycle is available.
         * <p>
         * This should only be called on the main thread.
         * <p>
         * Overriding this method is no longer supported and this method will be made
         * <code>final</code> in a future version of Fragment.
         *
         * @return A {@link LifecycleOwner} that represents the {@link #getView() Fragment's View}
         * lifecycle.
         * @throws IllegalStateException if the {@link #getView() Fragment's View is null}.
         */
        @MainThread
        @NonNull
        public LifecycleOwner getViewLifecycleOwner() {
            if (mViewLifecycleOwner == null) {
                throw new IllegalStateException("Can't access the Fragment View's LifecycleOwner when "
                        + "getView() is null i.e., before onCreateView() or after onDestroyView()");
            }
            return mViewLifecycleOwner;
        }
    
    /**
         * Retrieve a {@link LiveData} which allows you to observe the
         * {@link #getViewLifecycleOwner() lifecycle of the Fragment's View}.
         * <p>
         * This will be set to the new {@link LifecycleOwner} after {@link #onCreateView} returns a
         * non-null View and will set to null after {@link #onDestroyView()}.
         * <p>
         * Overriding this method is no longer supported and this method will be made
         * <code>final</code> in a future version of Fragment.
         *
         * @return A LiveData that changes in sync with {@link #getViewLifecycleOwner()}.
         */
        @NonNull
        public LiveData<LifecycleOwner> getViewLifecycleOwnerLiveData() {
            return mViewLifecycleOwnerLiveData;
        }
    
    null onDestroyView를 호출한 후에 참조하면 오류가 발생합니다getViewLifecycleOwner.
    Overriding this method is no longer supported and this method will be made <code>final</code> in a future version of Fragment.
    
    나는 이 문장이 매우 마음에 든다

    Link

  • Suspending over Views
  • https://medium.com/androiddevelopers/suspending-over-views-19de9ebd7020
  • 더 똑똑해 보이는 녀석
  • 좋은 웹페이지 즐겨찾기