ここでは簡単なLiveDataBusを使用し、以下の利点があるのLiveData:
LiveDataの利点 | 説明 |
UIとダースのデータの整合性よりも | LiveDataはUIを更新し、データの発生を通知オブザーバーパターンを使用して |
メモリリークを避けます | アセンブリが破壊する(破壊)バインドされた観察者がすぐに自動的に独自のデータをクリーンアップしますときに、視聴者は、コンポーネントのライフサイクルにバインドされています |
ベンは、停止状態での活動の崩壊を引き起こすことはありません | バックグラウンドでの活動状態がイベントLiveDataのいずれかを受け取ることはありません |
あなたはライフサイクルに起因する問題を解決する必要はありません。 | LiveDataがバインドされたコンポーネントのライフサイクルを感知することができ、データのみがアクティブ状態の変化に気づくでしょう |
リアルタイムデータブラシ | アセンブリがアクティブ状態または非アクティブ状態からアクティブ状態にあるときは、常に最新のデータを受け取ります |
コンフィギュレーションの変更を問題解決 |
画面が回転しているか、最新のデータを受信することができ、すぐに再起動リサイクル |
LiveDataBusは(画像は、モックをよく見ていません)全体のアーキテクチャを見てみましょう。
そして、(そしてここで私はコードを直接置く)、(バグがあるに見える)LiveDataBusの使用で新しいLiveDataBus1クラスを見て:
1 パブリック最終クラスLiveDataBus1 { 2 3 プライベート最終地図の<string、MutableLiveData <オブジェクト>> バス。 4 5 プライベートLiveDataBus1(){ 6つの バス= 新規 HashMapの<> (); 7 } 8 9 プライベート 静的 クラスSingletonHolder { 10 プライベート 静的最終LiveDataBus1 DATA_BUS = 新しいLiveDataBus1()。 11 } 12 13 パブリック 静的 LiveDataBus1 GET(){ 14 リターンSingletonHolder.DATA_BUS。 15 } 16 17 公衆 <T> MutableLiveData <T>さらに、getChannel(文字列ターゲットクラス<T> 型){ 18 であれば(!bus.containsKey(ターゲット)){ 19 bus.put(ターゲット、新しい MutableLiveData <> ()); 20 } 21 リターン(MutableLiveData <T>)バス。取得(ターゲット)。 22 } 23 24 公衆 MutableLiveData <OBJECT> さらに、getChannel(文字列対象){ 25 リターンさらに、getChannel(ターゲットオブジェクト。クラス)。 26 } 27 }
その後、メッセージを送信するためのボタンで、MainActivtyで使用され、新しいインターフェイスを起動します。
1 @Override 2 公共 ボイドのonClick(ビュービュー){ 3 LiveDataBus1。取得().getChannel("ナイス").setValue(" こんにちはアンドロイド!" ); 4 意図意図= 新しいテント(この、TestActivity。クラス)。 5 startActivity(インテント)。 6 }
onCreate新しいインターフェイスのためにサインアップし、その後、受信したメッセージの内容を表示するのTextViewコントロールを追加します。
1 LiveDataBus1。得る().getChannel(" ナイス"、ストリングクラス).observe(この、新たなオブザーバーの<string> (){ 2 @Override 3 公共 ボイド(文字列S){onChangedイベント 4 txtTest.setText(S); 5 } 6 });
起動項目、ボタンをクリックして、すぐに発見のTextViewコントロールの表示内容に新しいインターフェイスにジャンプし、これは望ましい結果ではありません。
エフェクトの2種類が、新しいLiveDataBusクラスは、私は、コードを直接投稿しました:
1 public class LiveDataBus { 2 3 private final Map<String,BusMutableLiveData<Object>> bus; 4 5 private LiveDataBus(){ 6 bus = new HashMap<>(); 7 } 8 9 private static class SingletonHolder{ 10 private static final LiveDataBus DEFAULT_BUS = new LiveDataBus(); 11 } 12 13 public static LiveDataBus get(){ 14 return SingletonHolder.DEFAULT_BUS; 15 } 16 17 public <T> MutableLiveData<T> with(String key,Class<T> type){ 18 if(!bus.containsKey(key)) { 19 bus.put(key, new BusMutableLiveData<>()); 20 } 21 return (MutableLiveData<T>) bus.get(key); 22 } 23 24 public MutableLiveData<Object> with(String key){ 25 return with(key,Object.class); 26 } 27 28 private static class ObserverWrapper<T> implements androidx.lifecycle.Observer<T> { 29 30 private androidx.lifecycle.Observer<T> observer; 31 32 public ObserverWrapper(Observer<T> observer) { 33 this.observer = observer; 34 } 35 36 @Override 37 public void onChanged(@Nullable T t) { 38 if (observer != null) { 39 if (isCallOnObserve()) { 40 return; 41 } 42 observer.onChanged(t); 43 } 44 } 45 46 private boolean isCallOnObserve() { 47 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 48 if (stackTrace != null && stackTrace.length > 0) { 49 for (StackTraceElement element : stackTrace) { 50 if ("android.arch.lifecycle.LiveData".equals(element.getClassName()) && 51 "observeForever".equals(element.getMethodName())) { 52 return true; 53 } 54 } 55 } 56 return false; 57 } 58 } 59 60 private static class BusMutableLiveData<T> extends MutableLiveData<T> { 61 62 private Map<Observer, Observer> observerMap = new HashMap<>(); 63 64 @Override 65 public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { 66 super.observe(owner, observer); 67 try { 68 hook(observer); 69 } catch (Exception e) { 70 e.printStackTrace(); 71 } 72 } 73 74 @Override 75 public void observeForever(@NonNull Observer<? super T> observer) { 76 if (!observerMap.containsKey(observer)) { 77 observerMap.put(observer, new ObserverWrapper(observer)); 78 } 79 super.observeForever(observerMap.get(observer)); 80 } 81 82 @Override 83 public void removeObserver(@NonNull Observer<? super T> observer) { 84 Observer realObserver = null; 85 if (observerMap.containsKey(observer)) { 86 realObserver = observerMap.remove(observer); 87 } else { 88 realObserver = observer; 89 } 90 super.removeObserver(realObserver); 91 } 92 93 private void hook(@NonNull Observer<? super T> observer) throws Exception { 94 //get wrapper's version 95 Class<LiveData> classLiveData = LiveData.class; 96 Field fieldObservers = classLiveData.getDeclaredField("mObservers"); 97 fieldObservers.setAccessible(true); 98 Object objectObservers = fieldObservers.get(this); 99 Class<?> classObservers = objectObservers.getClass(); 100 Method methodGet = classObservers.getDeclaredMethod("get", Object.class); 101 methodGet.setAccessible(true); 102 Object objectWrapperEntry = methodGet.invoke(objectObservers, observer); 103 Object objectWrapper = null; 104 if (objectWrapperEntry instanceof Map.Entry) { 105 objectWrapper = ((Map.Entry) objectWrapperEntry).getValue(); 106 } 107 if (objectWrapper == null) { 108 throw new NullPointerException("Wrapper can not be bull!"); 109 } 110 Class<?> classObserverWrapper = objectWrapper.getClass().getSuperclass(); 111 Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion"); 112 fieldLastVersion.setAccessible(true); 113 //get livedata's version 114 Field fieldVersion = classLiveData.getDeclaredField("mVersion"); 115 fieldVersion.setAccessible(true); 116 Object objectVersion = fieldVersion.get(this); 117 //set wrapper's version 118 fieldLastVersion.set(objectWrapper, objectVersion); 119 } 120 } 121 }
同样是在MainAct按钮中发送消息,跳转到新页面,这里我就直贴出发送消息的代码:
1 LiveDataBus.get().with("test").setValue("Hello Android!");
然后在新新界面中添加一个Button控件,然后先把注册订阅放在Button的点击事件中:
1 LiveDataBus.get().with("test",String.class).observe(this, new Observer<String>() { 2 @Override 3 public void onChanged(String s) { 4 txtTest.setText(s); 5 } 6 }); 7 }
做完以上操作后,点击MainActivity的Button跳到新界面,再然后点击新界面的Button控件,TextView控件的值就改变了,LiveDataBus的简单使用就说到这里了。