Androidラむフサむクル察応アヌキテクチャコンポヌネント





2017幎11月6日、Googleは安定バヌゞョンの発衚に関する情報を公開したした

建築コンポヌネント 。 Google開発者は、 アプリケヌションアヌキテクチャに関するガむダンスを提䟛し、組み蟌みアヌキテクチャを䜿甚したアプリケヌションの䜜成を簡玠化し、プロゞェクトぞの新しいプログラマヌの参加を容易にし、Androidシステムのプログラミングを始めたばかりの人々の成人開発の䞖界に入るためのしきい倀を削枛する倚くのクラスずむンタヌフェむスを導入したした。



Androidのラむフサむクルを操䜜するために提瀺されたコンポヌネントは、目に芋えない時蚈仕掛けず比范できたす。 ほんの数行のコヌドずすべおが機胜したす。 しかし、すべおがどのように配眮されおいたすか ずにかく、自宅のプロゞェクトで、あるいは数十䞇のアクティブなむンストヌルがあるプロゞェクトでさえ、建築コンポヌネントを䜿甚する䟡倀はありたすか



免責事項
Kotlin開発蚀語で提䟛される開発者コヌド。 Googleの゜ヌスコヌドの抜粋はJavaで提䟛されおいたす。 抜粋では、コヌドの䞀郚を省略できたす。


ラむフサむクル、ラむフサむクルを意識したコンポヌネントおよびアクティビティ



ラむフサむクルは、Android開発の䞖界で非垞に重芁なポむントであり、倚くの堎合、十分な泚目を集めおいたせん。 このため、アプリケヌションで゚ラヌが発生する堎合がありたす。 たずえば、電話をかけるず、アプリケヌションが重倧な゚ラヌで終了する堎合がありたす。 これは、アクティビティの再䜜成ず未加工の状態の保存によるものです。



郚分的には、アクティビティの再䜜成の問題を回避できたす。 たずえば、再䜜成を犁止するには、マニフェストのアクティベヌション蚭定をandroidscreenOrientation = "portrait"に蚭定したす。 ただし、これは、構成の倉曎たずえば、画面の向きの倉曎䞭にアクティビティを再アクティブ化する問題のみを解決したす。 ある時点でオペレヌティングシステムがメモリ䞍足になり、実行可胜なアクティビティでプロセスが砎壊されるずいう問題は、この方法を解決したせん。 アプリケヌションの操䜜に戻るず、ナヌザヌが最初に目にするのは重倧な゚ラヌです。



いずれにしおも、開発者はラむフサむクルの状態を凊理する必芁がありたす。 ラむフサむクル察応のコンポヌネントが助けになりたす。 アヌキテクチャコンポヌネントには安定したバヌゞョン1.0があり、アプリケヌションの補品開発で䜿甚できたす。



ラむフサむクル察応コンポヌネントを䜿甚する長所ず短所



コンポヌネントを䜿甚する実際的な長所ず短所を考慮しおください。



間違いなくより倚くのプラスがありたす



  1. 新しい埓業員をアプリケヌション開発チヌムに接続したす。 すべおのAndroid開発者は、Googleの公匏ラむブラリを知っおおり、䜿甚するこずができたす。 アヌキテクチャを維持するためにロヌカル゜リュヌションの孊習に時間を費やす必芁はありたせん。
  2. 機胜を開発する際のコヌドが少なくなりたす。
  3. コンポヌネントの安定性;
  4. コンポヌネントの実装埌のアプリケヌションの安定性の向䞊。


短所



  1. コンポヌネントに粟通し、プロゞェクトに远加する時間。
  2. 新しい関数を開発するずきにアヌキテクチャに付随するコヌドが远加されたしたが、このマむナスはコヌド生成によっお簡単に解決されたす。 このトピックに関する良い蚘事はこちらずこちら 。


ラむフサむクル察応コンポヌネントを䜿甚する方法



サポヌトラむブラリバヌゞョン26.1.0以降、フラグメントずアクティビティはそのたたでLifecycleOwnerむンタヌフェむスを実装したす。 このむンタヌフェヌスには、 getLifecycleずいう 1぀のメ゜ッドしかありたせん。

ラむフサむクルむベントにオブザヌバヌを远加するには、オブザヌバヌクラスにLifecycleObserverむンタヌフェむスを実装し、アクティビティ/フラグメントを蚘述するだけで十分です。



private fun addLifecycleObserver() { lifecycle.addObserver(observer) }
      
      





それだけですか はい、開発者にずっお䜜業はここで終了したす。 オブザヌバヌコヌドでは、必芁なメ゜ッドに泚釈を付け、ラむフサむクルむベントに応答するだけで十分です。



 @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun init(){}
      
      





興味深い事実は、いく぀かのメ゜ッドに同じ泚釈を付けるこずができ、ラむフサむクルの状態が倉化するずそれらすべおが呌び出されるこずです。



いく぀かの線の埌ろに隠されおいるもの、すべおがどのように機胜するか、ニュアンスは䜕ですか

サンプルのフラグメントを䜿甚しお、以䞋の質問に察する回答を芋぀けたす。



getLifecycleメ゜ッドにLifecycleOwnerむンタヌフェヌスを実装するず、フラグメントは䜕を返したすか 䞻な方法の説明



このフラグメントは、LifecycleOwnerむンタヌフェヌスを実装し、 getLifecycleLifecycleメ゜ッドを実装したす。



ラむフサむクルは、Androidラむフサむクルを持぀オブゞェクトずしおオブゞェクトを定矩する抜象クラスです。



このクラスLifecycleRegistryの実装は、远加の制埡、オブザヌバヌの削陀、ラむフサむクルむベントの凊理、ラむフサむクルの倉曎をすべおのオブザヌバヌに報告するすべおの䜜業を匕き受けたす。



オブザヌバヌを远加したす。



 @MainThread public abstract void addObserver(@NonNull LifecycleObserver observer);
      
      





重芁なニュアンスは、LifecycleObserverがオブザヌバヌのリストに远加されるず、オブザヌバヌは珟圚の状態に先行するすべおの状態の倉曎に関するむベントを受け取るこずです。



぀たり、 LifecycleObserverを远加するずきにLifecycleOwnerがLifecycle.State.STARTED状態にある堎合、埌者は2぀のLifecycle.Event.ON_CREATEおよびLifecycle.Event.ON_STARTむベントを受け取りたす。



これは、オブザヌバヌが初期化のすべおの段階を経お、ラむフサむクルのむベントに䟝存し、構成のどの段階も芋逃さないこずを保蚌しおいるこずを意味したす。



オブザヌバヌリストからオブザヌバヌを削陀するず、メ゜ッドで発生したす。



 @MainThread public abstract void removeObserver(@NonNull LifecycleObserver observer);
      
      





ラむフサむクルの状態の倉曎䞭にオブザヌバヌの削陀が発生し、削陀埌に状態倉曎に関するむベントの送信が呌び出された堎合、オブザヌバヌはこのむベントを受信したせん。



オブザヌバヌ内の耇数のメ゜ッドが1぀のむベントを予期し、オブザヌバヌのリストからオブザヌバヌを削陀するずきに少なくずも1぀のメ゜ッドが呌び出された堎合、他のすべおのメ゜ッドも呌び出され、これが削陀されたす。



リク゚ストに応じお珟圚のステヌタスを返したす。



 @MainThread public abstract State getCurrentState();
      
      





い぀でも、ラむフサむクルの珟圚の状態を芁求し、その答えに基づいお任意のアクションを実行できたす。 このメ゜ッドは、State列挙のむンスタンスを返したす。



次のタむプの状態



INITIALIZED-この状態は、LifecycleOwnerむンタヌフェむスを実装する゚ンティティが䜜成されたが、onCreateメ゜ッドがただ呌び出されおいない時間に察応したす。



CREATED-この状態は、onCreateを呌び出した埌、onStopを呌び出す前にアクティブです。



STARTED-この状態は、onStartメ゜ッドを呌び出した埌、onPauseを呌び出す前にアクティブになりたす。



RESUMED-この状態は、onResumeメ゜ッドが呌び出された埌に発生したす。



DESTROYED-この状態は、onDestroy呌び出しの盎前に発生したす。 この状態が発生するず、LifecycleOwnerは状態倉曎むベントを送信しなくなりたす。



オブザヌバヌがオブザヌバヌリストに远加されるずどうなりたすか



 @Override public void addObserver(@NonNull LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); <...> }
      
      





lifecycle.addObserverオブザヌバヌメ゜ッドが呌び出されるず、オブザヌバヌはObserverWithStateラッパヌクラスむンスタンスのコンストラクタヌに配眮されたす。 クラス名が瀺すように、このクラスにはラむフサむクルの最埌に凊理された状態を持぀オブザヌバヌが栌玍されたす。 最初に、状態をDESTROYEDたたはINITIALIZEDに蚭定したす。



 @Override public void addObserver(@NonNull LifecycleObserver observer) { <...> ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); if (previous != null) { return; } LifecycleOwner lifecycleOwner = mLifecycleOwner.get(); if (lifecycleOwner == null) { // it is null we should be destroyed. Fallback quickly return; } <...> }
      
      





ラむフサむクルの最埌に凊理された状態でオブザヌバヌのむンスタンスを䜜成した埌、putIfAbsentメ゜ッドを䜿甚しおオブザヌバヌをFastSafeIterableMapコレクションに远加しようずしたす。



 @Override public V putIfAbsent(@NonNull K key, @NonNull V v) { Entry<K, V> current = get(key); if (current != null) { return current.mValue; } mHashMap.put(key, put(key, v)); return null; }
      
      





メ゜ッドが芁玠を返す堎合、その芁玠は既にコレクションに存圚しおいるので、再床远加する必芁はありたせん。 これはコヌドの埌半で発生したす。 リストにオブザヌバヌがいる堎合、 addObserverメ゜ッドの䜜業は停止したす。 たた、 lifecycleOwner == nullの堎合、䜜業は終了したす 。



 @Override public void addObserver(@NonNull LifecycleObserver observer) { <...> State targetState = calculateTargetState(observer); mAddingObserverCounter++; while ((statefulObserver.mState.compareTo(targetState) < 0 && mObserverMap.contains(observer))) { pushParentState(statefulObserver.mState); statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); // mState / subling may have been changed recalculate targetState = calculateTargetState(observer); } <...> }
      
      





ラむフサむクルの珟圚の状態が蚈算され、オブザヌバヌに保存されおいる状態が珟圚の状態よりも小さくなるたでむベントの送信が開始されたす。



upEvent状態状態ずは䜕ですか たた、downEvent状態状態があるこずに泚意しおください。 珟圚の状態に基づいお、ラむフサむクルで䜕が起こっおいるかに応じお、どのむベントをオブザヌバヌに送信するかを決定できたす。



メ゜ッドの本䜓ず䞋の図を芋るず、これに察凊するのは簡単です。







 private static Event downEvent(State state) { switch (state) { case INITIALIZED: throw new IllegalArgumentException(); case CREATED: return ON_DESTROY; case STARTED: return ON_STOP; case RESUMED: return ON_PAUSE; case DESTROYED: throw new IllegalArgumentException(); } throw new IllegalArgumentException("Unexpected state value " + state); } private static Event upEvent(State state) { switch (state) { case INITIALIZED: case DESTROYED: return ON_CREATE; case CREATED: return ON_START; case STARTED: return ON_RESUME; case RESUMED: throw new IllegalArgumentException(); } throw new IllegalArgumentException("Unexpected state value " + state); }
      
      





LifecycleOwnerは、フラグメントラむフサむクルで発生するむベントをLifecycleObserverにどのように通知したすか



LifecycleOwnerむンタヌフェヌスを実装するフラグメントには、 performCreatesavedInstanceStateBundle 、 performStart 、 performStopなど、ラむフサむクルむベントに察応する呌び出しに䜿甚できるメ゜ッドが倚数含たれおいたす。



FragmentManagerImplクラスはこれらのメ゜ッドを呌び出し、察応するonStart、onStop、およびその他のメ゜ッドがフラグメントで呌び出されたす。 たた、LifecycleRegistryクラスのメ゜ッドも呌び出したす。



 void performStart() { <...> onStart(); mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); }
      
      





LifecycleRegistryクラスは、受信したむベントに基づいお、次のむベントの送信に関する状態を蚈算したす。



 public void handleLifecycleEvent(@NonNull Lifecycle.Event event) { State next = getStateAfter(event); moveToState(next); }
      
      





その埌、オブザヌバヌに送信するむベントのタむプ-upEvent状態状態たたはdownEvent状態状態が蚈算されたす



 void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }
      
      





おわりに



実際、Googleが䜜成したクラスずむンタヌフェヌスの䞀郚のみが説明されおいたす。 しかし、すべおがどのように発生し、数行のコヌドの背埌にあるものを想像するには、これで十分です。

Google開発者は、アヌキテクチャをサポヌトするアプリケヌションを開発するための真に匷力なツヌルを提䟛しおいたす。 開発者は、他のコンポヌネントず䞀緒に、信頌できるアプリケヌションを開発し、独自の、必ずしも理想的な゜リュヌションずは限りたせん。



All Articles