LiveDataBusの簡単な使用

ここでは簡単な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的简单使用就说到这里了。

おすすめ

転載: www.cnblogs.com/Mr-Deng/p/11647009.html