Android官方架构组件介绍之LifeCycle(一)

Android官方架构组件介绍之LifeCycleandroid

下面是官方提供的Android App开发的架构图:网络

 

从上图能够看到一些关键字:ViewModel,LiveData,Room等。其实看了上面视频的会发现Google官方Android架构组件一共包括如下几个:架构

  • LifeCycle : 与Activity和Fragment的生命周期有关
  • LiveData :异步可订阅数据,也是生命周期感知
  • ViewModel :视图数据持有模型,也是生命周期感知
  • Room :SQLite抽象层,用于简化SQLite数据存储

这篇文章主要讲解LifeCycle在项目的简单用法异步

AS中添加依赖

首先在工程根目录的build.gradle中添加一下内容:maven

allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }  //添加此行
    }
}

而后在应用目录下的build.gradle中添加如下依赖:ide

//For Lifecycles, LiveData, and ViewModel
compile "android.arch.lifecycle:runtime:1.0.0-alpha1"
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"

//For Room
compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"

LifeCycle相关使用

在咱们平时的项目中常常会遇到不少须要依赖生命周期的逻辑处理,好比有这么一个需求。
在某个Activity咱们须要在屏幕上展示用户的地理位置。简单的实现方法以下:测试

lass MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service
    }
}

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {
            // update UI
        });
  }

    public void onStart() {
        super.onStart();
        myLocationListener.start();
    }

    public void onStop() {
        super.onStop();
        myLocationListener.stop();
    }
}

虽然以上代码看起来很简洁,但在实际项目中的onStart,onStop方法可能会变得至关庞大。
此外,实际状况可能并不像上面这么简单,例如咱们须要在start位置监听前作用户状态检测,检测是一个耗时的任务,那么颇有可能在检测结束前用户提早退出了Activity,这时候就会致使myLocationListener.start()myLocationListener.stop()后面调用,从而引发不少难以定位的问题。代码以下:gradle

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, location -> {
            // update UI
        });
    }

    public void onStart() {
        super.onStart();
        Util.checkUserStatus(result -> {
            // what if this callback is invoked AFTER activity is stopped?
            if (result) {
                myLocationListener.start();
            }
        });
    }

    public void onStop() {
        super.onStop();
        myLocationListener.stop();
    }
}

这时候就该今天的主角LifeCycle出场了。它提供了一套接口帮助你处理这些问题。ui

LifeCycle

LifeCyle类持有Activity或者Fragment的生命周期相关信息,而且支持其余对象监听这些状态。this

LifeCyle有两个枚举用于追踪生命周期中的状态。

Event

这是生命周期的事件类,会在Framework和LifeCycle间传递,这些事件映射到Activity和Fragment的回调事件中。

State

LifeCycle所持有Activity或Fragment的当前状态。

一个类想要监听LifeCycle的状态,只须要给其方法加上注解:

public class MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
    }
}
aLifecycleOwner.getLifecycle().addObserver(new MyObserver());

LifeCycleOwner

LifeCycleOwner是一个只有一个方法的接口用于代表其有一个LifeCycle对象。这个方法为getLifecycle()
这个对象给Acitivity,Fragment和LifeCycle提供了一个很好的抽象关系,Activity和Fragment只要实现这个接口就能配合LifeCycle实现生命周期监听。

注意:因为目前LifeCycle处于alpha阶段,因此Fragment和AppCompatActivity并不会实现这些方法,在此以前,可使用LifecycleActivityLifecycleFragment。等LifeCycle趋于稳定后,Fragment和AppCompatActivity会默认实现这些。

对于以前的位置监听的例子,咱们可让MyLocationListener继承LifecycleObserver,在onCreate中使用LifeCycle进行初始化,剩下的问题则没必要担忧了。由于MyLocationListener有能力进行生命周期的判断。

class MyActivity extends LifecycleActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        //此处进行初始化getLifecycle()传入LifeCycle对象
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        //检测用户状态并启用监听
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}

下面看一下MyLocationListener

class MyLocationListener implements LifecycleObserver {
    private boolean enabled = false;
    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() {
        if (enabled) {
           // connect
        }
    }

    public void enable() {
        enabled = true;
        //
        if (lifecycle.getState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() {
        // disconnect if connected
    }
}

LifeCycle最重要的特性就是在⓵处,他能够提供主动查询生命周期状态的方法。这样就避免了上面遇到的myLocationListener.start()myLocationListener.stop()后面调用的问题。

经过以上的实现,咱们的LocationListener是彻底的生命周期感知了,它能够进行本身的初始化和资源清理而没必要受Activity或者Fragment的管理。这时候若是咱们在其余Activity或者Fragment中使用LocationListener,咱们只须要初始化它就好了,没必要再担忧生命周期对它的影响,由于它内部会作好这一切。

经过LefeCycle工做的类咱们称之为生命周期感知。鼓励须要使用Android生命周期的类的库提供生命周期感知组件,以便客户端能够轻松地在客户端上集成这些类,而无需手动生命周期管理。

LiveData就是生命周期感知组件的示例,将LiveData和ViewModel一块儿使用,能够在遵循Android生命周期的状况下,更容易的使用数据来填充UI。

生命周期的最佳实践

  • 保持你的UI(Activity和Fragment)尽量简洁。它们不该该试图获取它们的数据而是使用ViewModel来执行此操做,并经过LiveData的回调将数据更新到UI中。
  • 尝试编写数据驱动的UI,你的UI的责任是在数据更改时更新视图,或将用户操做通知给ViewModel。
  • 将你的数据逻辑放在ViewModel类中。 ViewModel应该做为UI和其余数据操做的链接器。值得注意的是,ViewModel并不负责提取数据(例如,从网络)。相反,ViewModel应该调用其余接口来执行此工做,而后将结果提供给UI。
  • 使用Data Binding可让你的的UI代码变得至关干净利落。这将使你的UI更具声明性,并最大限度地减小书写UI更新的代码。若是您更喜欢在Java中执行此操做,请使用像Butter Knife这样的库来避免使用样板代码并进行更好的抽象。
  • 若是你有一个复杂的UI,请考虑建立一个Presenter类来处理UI修改。这一般是过分架构的,但可能有助于使你的UI更容易测试。
  • 不要在ViewModel中引用View或Activity上下文。若是ViewModel在Activity或View销毁的状况下依旧存活,这时将致使内存泄漏。

补充

在自定义的Activity或Fragment中实现LifeCycleOwner,能够实现LifecycleRegistryOwner这个接口。而不是继承(LifeCycleFragment和LifeCycleActivity)

public class MyFragment extends Fragment implements LifecycleRegistryOwner {
    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }
}

若是你要在自定义的类中实现LifeCycleOwner,可使用LifecycleRegistry,可是你须要主动向其转发生命周期的事件。但若是你自定义类是Fragment和Activity的话而且它们实现的是LifecycleRegistryOwner,那么事件转发都是自动完成的。

相关文章
相关标签/搜索