Hement:LifeCycle的使用(五)

  • GitHub地址Hement:持续更新中
  • apk下载地址
    image.png
  • app详情
    app详情.png
  • 欢迎关注我的公众号
    公众号

  • LifeCycle

  • 在17年的谷歌IO大会上,Google官方向我们推出了 Android Architecture Components,其中谈到Android组件处理生命周期的问题,向我们介绍了 Handling Lifecycles
  • 由于和小组成员讨论过,感觉使用时机还没有到,而且那个时候我反编译微信的apk,发现也没有使用的到,所以这个框架的学习计划就不断地搁浅,前几天又反编译了一下微信的安卓apk,发现它使用了来减少代码的臃肿!
    推荐一个反编译工具

微信反编译的结果图.png

  • 所以就有必要了解它到底是个什么东西

  • 为什么要使用Lifecycle

  • 我们在处理Activity或者Fragment组件的生命周期相关时,不可避免会遇到这样的问题:
    我们在Activity的onCreate()中初始化某些成员(比如MVP架构中的Presenter,或者AudioManager、MediaPlayer等),然后在onStop中对这些成员进行对应处理,在onDestroy中释放这些资源,这样导致我们的代码也许会像这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

class MyPresenter{
public MyPresenter() {
}

void create() {
//do something
}

void destroy() {
//do something
}
}

class MyActivity extends AppCompatActivity {
private MyPresenter presenter;

public void onCreate(...) {
presenter= new MyPresenter ();
presenter.create();
}

public void onDestroy() {
super.onDestroy();
presenter.destory();
}
}
  • 代码没有问题,关键问题是,实际生产环境中 ,这样的代码会非常复杂,你最终会有太多的类似调用并且会导致 onCreate() 和 onDestroy() 方法变的非常臃肿。
  • 如何使用Lifecycle
    在前面我写过一篇文章Hement:MVP架构中的网络框架(RxJava2+Retrofit2+RxAndroid)(二)这是没有使用的Lifecycle的网络请求的Presenter必须在onDestroy时候去销毁view!

    1
    2
    3
    4
    5
    @Override
    protected void onDestroy() {
    super.onDestroy();
    mMainPresenter.detachView();
    }
  • 能不能集成到BasePresenter的中去呢?其实是可以滴,只需要把BasePresenter实现LifecycleObserver即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    public class NewBasePresenter<V extends IMvpView> implements LifecycleObserver {


    public static final String TAG = "NewBasePresenter";
    private V mMvpView;


    public void attachView(V mvpView) {
    mMvpView = mvpView;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
    Timber.tag(TAG).d("onDestroy lifecycle event.start ");
    detachView();
    }

    /**
    * 由于在每次这个方法都会去执行,所以可以这样进行
    * @param owner
    * @param event
    */
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    public void onLifecycleChanged(@NotNull LifecycleOwner owner, @NotNull Lifecycle.Event event) {

    }
    public void detachView() {
    mMvpView = null;
    }
    /**
    * 判断是否还在连接在一起的
    * @return
    */
    public boolean isViewAttached() {
    return mMvpView != null;
    }

    /**
    * 获取View
    * @return
    */
    public V getMvpView() {
    return mMvpView;
    }

    /**
    * 检查View是否附着
    */
    public void checkViewAttached() {
    if (!isViewAttached()) throw new MvpViewNotAttachedException();
    }

    public static class MvpViewNotAttachedException extends RuntimeException {
    public MvpViewNotAttachedException() {
    super("在绑定数据之前一定要绑定视图");
    }
    }

    /**
    * 这是Observer 中的 onServer ,当我们调用这个方法,直接就不会走到 onNext中去
    * @param disposable
    */
    public void dispose(Disposable disposable) {
    if (disposable != null && !disposable.isDisposed()) {
    disposable.dispose();
    }
    }
    }
  • 具体的Preseter的实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    public class NewNetWorkPresenter extends NewBasePresenter<NetWorkView> {


    private Disposable mDisposable;
    private final IRemoteServer mIRemoteServer;

    public NewNetWorkPresenter() {
    mIRemoteServer = IRemoteServer.Creator.newHementService();
    }

    @Override
    public void attachView(NetWorkView mvpView) {
    super.attachView(mvpView);
    }

    @Override
    public void detachView() {
    super.detachView();
    if (mDisposable != null) mDisposable.dispose();
    Timber.tag(TAG).d("onDestroy lifecycle event. end ");
    }
    public void loadData(String key,String day){
    //检查View是否附着在上面,不在直接抛出异常
    checkViewAttached();
    //检查是否往下运行
    dispose(mDisposable);
    loadData(key,day,new BaseObserver<SMResponse<ArrayList<TodayBean>>>(new SubscriberListener<SMResponse<ArrayList<TodayBean>>>() {

    @Override
    public void onSubscribe(Disposable disposable) {
    super.onSubscribe(disposable);
    mDisposable = disposable;
    }

    @Override
    public void onSuccess(SMResponse<ArrayList<TodayBean>> response) {
    getMvpView().getDataSuccess(response.result);
    }

    @Override
    public void onFail(String errorCode, String errorMsg) {
    getMvpView().getDataFail(errorCode,errorMsg);
    }

    @Override
    public void onError(Throwable e) {
    getMvpView().onError(e);
    }
    }));
    }
    public void loadData(String key, String day, BaseObserver observer) {
    Observable<SMResponse<ArrayList<TodayBean>>> today = mIRemoteServer.getToday(key, day);
    today.observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io())
    .subscribe(observer);
    }
    }
  • 在Activity中的使用,只需要使用这样使用,我们就能够检测到生命周期的使用,有兴趣的可以下载Apk查看日志!

1
2
3
4
5
6
7
8
9
private NewNetWorkPresenter mNewNetWorkPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_net_work);
mNewNetWorkPresenter = new NewNetWorkPresenter();
getLifecycle().addObserver(mNewNetWorkPresenter);

}
  • Lifecycle的升级使用
  • 假如我们有个这样的需求,某个页面需要去查询数据库展示数据,同时使用到RxJava2的依赖,查询数据的过程在子线程处理数据回调到UI线程,当突然有一天产品经理说这个页面的数据我们要从网络获取,那么你也不确定那到底是把代码删除了还是备份,这些你都不知道!所以这时候你就需要独立绑定getLifecycle().addObserver(mSyncLifecycleObserver);Activity只关心结果即可!代码如下
  • 在这里需要使用这个依赖
    1
    api  "com.jakewharton.rxrelay2:rxrelay:2.0.0"

image.png

  • SyncResponse

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class SyncResponse {
    public final SyncResponseEventType eventType;
    public final Events comment;

    public SyncResponse(SyncResponseEventType eventType, Events comment) {
    this.eventType = eventType;
    this.comment = comment;
    }
    }
    • SyncLifecycleObserver
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163

      package com.shiming.hement.lifecycle;

      import android.arch.lifecycle.Lifecycle;
      import android.arch.lifecycle.LifecycleObserver;
      import android.arch.lifecycle.OnLifecycleEvent;
      import android.widget.Toast;

      import com.shiming.hement.utils.Events;

      import org.w3c.dom.Comment;

      import io.reactivex.Completable;
      import io.reactivex.android.schedulers.AndroidSchedulers;
      import io.reactivex.disposables.CompositeDisposable;
      import io.reactivex.functions.Action;
      import io.reactivex.functions.Consumer;
      import io.reactivex.schedulers.Schedulers;
      import timber.log.Timber;

      /**
      * <p>
      *
      * </p>
      *
      * @author shiming
      * @version v1.0
      * @since 2018/12/18 10:44
      */

      public class SyncLifecycleObserver implements LifecycleObserver {

      private static final String TAG = "SyncLifecycleObserver";

      private final CompositeDisposable disposables = new CompositeDisposable();


      @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
      public void onCreate() {
      Timber.tag(TAG).d("onCreate lifecycle event.");
      }

      @OnLifecycleEvent(Lifecycle.Event.ON_START)
      public void onStart() {
      Timber.tag(TAG).d("onStart lifecycle event.");
      }

      @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
      public void onResume() {
      Timber.tag(TAG).d("onResume lifecycle event.");
      disposables.add(SyncRxBus.getInstance().toObservable()
      .subscribe(new Consumer<SyncResponse>() {
      @Override
      public void accept(SyncResponse syncResponse) throws Exception {
      handleSyncResponse(syncResponse);
      }
      }, new Consumer<Throwable>() {
      @Override
      public void accept(Throwable throwable) throws Exception {
      Timber.tag(TAG).d("onResume lifecycle event. Throwable= %s",throwable);
      }
      }));
      }

      private void handleSyncResponse(SyncResponse response) {
      if (response.eventType == SyncResponseEventType.SUCCESS) {
      onSyncSuccess(response.comment);
      } else {
      onSyncFailed(response.comment);
      }
      }

      private void onSyncSuccess(Events comment) {
      Timber.tag(TAG).d("received sync comment success event for comment %s", comment);
      disposables.add(Completable.fromAction(new Action() {
      @Override
      public void run() throws Exception {
      doWhat();
      Thread thread = Thread.currentThread();
      Timber.tag(TAG).i(thread.toString());
      }
      })
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(new Action() {
      @Override
      public void run() throws Exception {
      Timber.tag(TAG).d(" success");
      }
      },
      new Consumer<Throwable>() {
      @Override
      public void accept(Throwable throwable) throws Exception {
      Timber.tag(TAG).e(throwable, " error");
      }
      }));
      }

      /**
      * 可以做些子线程的数据操作
      */
      private void doWhat() {

      }
      private void onSyncFailed(Events comment) {
      Timber.tag(TAG).d("received sync comment failed event for comment %s", comment);
      disposables.add(Completable.fromAction(new Action() {
      @Override
      public void run() throws Exception {
      doWhat();
      }
      })
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(new Action() {
      @Override
      public void run() throws Exception {
      Timber.tag(TAG).d(" success");
      }
      },
      new Consumer<Throwable>() {
      @Override
      public void accept(Throwable throwable) throws Exception {
      Timber.tag(TAG).e(throwable, " error");
      }
      }));
      }

      /**
      * 12-19 15:35:52.317 29721-29721/com.shiming.hement D/SyncLifecycleObserver: received sync comment success event for comment Events=我是NewRxBusDemoActivity中发出成功的事件
      * 12-19 15:35:52.318 29721-29834/com.shiming.hement I/SyncLifecycleObserver: Thread[RxCachedThreadScheduler-2,5,main]
      * 12-19 15:35:52.318 29721-29721/com.shiming.hement D/SyncLifecycleObserver: received sync comment success event for comment Events=我是NewRxBusDemoActivity中发出成功的事件
      * 12-19 15:35:52.319 29721-29835/com.shiming.hement I/SyncLifecycleObserver: Thread[RxCachedThreadScheduler-3,5,main]
      * 12-19 15:35:52.320 29721-29721/com.shiming.hement D/SyncLifecycleObserver: received sync comment success event for comment Events=我是NewRxBusDemoActivity中发出成功的事件
      * 12-19 15:35:52.321 29721-29834/com.shiming.hement I/SyncLifecycleObserver: Thread[RxCachedThreadScheduler-2,5,main]
      * 12-19 15:35:52.323 29721-29721/com.shiming.hement D/SyncLifecycleObserver: success
      * 12-19 15:35:52.330 29721-29721/com.shiming.hement D/SyncLifecycleObserver: success
      */
      @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
      public void onPause() {
      Timber.tag(TAG).d("onPause lifecycle event.");
      // 如果不在这里
      disposables.clear();
      }

      @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
      public void onStop() {
      Timber.tag(TAG).d("onStop lifecycle event.");
      }

      @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
      public void onDestroy() {
      Timber.tag(TAG).d("onDestroy lifecycle event.");
      }

      /**
      * 所有的事件都会输出
      */
      @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
      public void onAny() {
      Timber.tag(TAG).d("onAny 所有的事件都会输出");
      }
      }
  • SyncResponseEventType

    1
    2
    3
    4
    5

    public enum SyncResponseEventType {
    SUCCESS,
    FAILED
    }
  • SyncRxBus

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    public class SyncRxBus {

    private static SyncRxBus instance;
    private final PublishRelay<SyncResponse> relay;

    public static synchronized SyncRxBus getInstance() {
    if (instance == null) {
    instance = new SyncRxBus();
    }
    return instance;
    }

    private SyncRxBus() {
    relay = PublishRelay.create();
    }

    public void post(SyncResponseEventType eventType, Events comment) {
    relay.accept(new SyncResponse(eventType, comment));
    }

    public Observable<SyncResponse> toObservable() {
    return relay;
    }
    }
  • 在Activity中的使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // 如果使用的多的话,可以放在BaseActivity中
    private SyncLifecycleObserver mSyncLifecycleObserver = new SyncLifecycleObserver();


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rx_bus_layout);
    getLifecycle().addObserver(mSyncLifecycleObserver);

    findViewById(R.id.btn_mock_send_s_onclick).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Events events = new Events("我是NewRxBusDemoActivity中发出成功的事件");
    SyncRxBus.getInstance().post(SyncResponseEventType.SUCCESS, events);
    }
    });
    findViewById(R.id.btn_mock_send_f_onclick).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Events events = new Events("我是NewRxBusDemoActivity中发出失败的事件");
    SyncRxBus.getInstance().post(SyncResponseEventType.FAILED, events);
    }
    });
  • 如果后续我们不需要使用的话,直接就把Activity中两行代码注释掉就行~~~

    • GitHub地址Hement:持续更新中
  • 感谢以下博客对我的帮助


 上一篇
SQL学习 SQL学习
欢迎关注我的公众号1、SQL简介SQL:Structured Query Language的缩写(结构化查询语言)是一种定义、操作、管理关系数据库的句法 结构化查询语言的工业标准由ANSI(美国国家标准学会,ISO的成员之一)维护。 D
2019-03-04 Shiming_Li
下一篇 
Hement:项目中的三方依赖(四) Hement:项目中的三方依赖(四)
欢迎关注我的公众号 GitHub地址:Hement:持续更新中 由于使用Dagger2的未知性,所以创建一个分支没有使用Dagger2 Hement 1、RxPermissions 版本0.10.2 使用方式 初始化 1RxP
2018-12-13 Shiming_Li
  目录