Android Jetpack学习之Lifecycle

本文旨在记录本人学习Android Jetpack的过程,如有疏漏请指出!

传送门

 Handling Lifecycles with Lifecycle-Aware Components 

译:使用生命周期感知组件处理生命周期

Lifecycle-aware components perform actions in response to a change in the lifecycle status of another component, such as activities and fragments. These components help you produce better-organized, and often lighter-weight code, that is easier to maintain.

 译:Lifecycle感知组件执行操作,以响应另一个组件生命周期状态的更改,例如activities和fragments。这些组件可以帮助您生成更有组织、更容易维护的轻量级代码。

A common pattern is to implement the actions of the dependent components in the lifecycle methods of activities and fragments. However, this pattern leads to a poor organization of the code and to the proliferation of errors. By using lifecycle-aware components, you can move the code of dependent components out of the lifecycle methods and into the components themselves.

译: 一个常见的模式是在activities和fragments的生命周期方法中实现依赖组件的操作。但是,这种模式会导致代码组织不良和错误的增加。通过使用lifecycle感知组件,您可以将依赖组件的代码从生命周期方法转移到lifecycle组件本身。

The android.arch.lifecycle package provides classes and interfaces that let you build lifecycle-aware components—which are components that can automatically adjust their behavior based on the current lifecycle state of an activity or fragment.

 译: android.arch.lifecycle包中提供了一些类和接口,这些类和接口允许您构建具有lifecycle感知组件,这些组件可以根据activity或fragment的当前生命周期状态自动调整它们的行为。

dependencies {
    def lifecycle_version = "2.0.0"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx

    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}

声明依赖项的说明。

Most of the app components that are defined in the Android Framework have lifecycles attached to them. Lifecycles are managed by the operating system or the framework code running in your process. They are core to how Android works and your application must respect them. Not doing so may trigger memory leaks or even application crashes.

译:Android框架中定义的大多数应用程序组件都具有附加的生命周期。生命周期由运行在流程中的操作系统或框架代码管理。它们是Android工作原理的核心,您的应用程序必须尊重它们。不这样做可能会引发内存泄漏,甚至应用程序崩溃。

 Imagine we have an activity that shows the device location on the screen. A common implementation might be like the following:

译:假设我们有一个activity在屏幕上显示设备位置。常见的实现可能如下所示

class 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;

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

    @Override
    public void onStart() {
        super.onStart();
        myLocationListener.start();
        // manage other components that need to respond
        // to the activity lifecycle
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
        // manage other components that need to respond
        // to the activity lifecycle
    }
}

Even though this sample looks fine, in a real app, you end up having too many calls that manage the UI and other components in response to the current state of the lifecycle. Managing multiple components places a considerable amount of code in lifecycle methods, such as onStart() and onStop(), which makes them difficult to maintain.

译: 尽管这个示例看起来很好,但是在实际应用程序中,您最终会有太多的调用来管理UI和其他组件,以响应生命周期的当前状态。管理多个组件会在生命周期方法中放置大量的代码,比如onStart()和onStop(),这使得它们很难维护。

Moreover, there's no guarantee that the component starts before the activity or fragment is stopped. This is especially true if we need to perform a long-running operation, such as some configuration check in onStart(). This can cause a race condition where the onStop() method finishes before the onStart(), keeping the component alive longer than it's needed.

译: 此外,不能保证组件在activity或fragment停止之前启动。如果我们需要执行长时间运行的操作,比如在onStart()中做一些配置检查,这一点尤其正确。这可能会导致紊乱,即onStop()方法在onStart()之前结束,从而使组件存活的时间超过所需的时间。

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

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

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

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

The android.arch.lifecycle package provides classes and interfaces that help you tackle these problems in a resilient and isolated way.

译:  android.arch.lifecycle包中提供了一些类和接口,这些类和接口可以帮助您以一种灵活和隔离的方式处理这些问题。

-------------------------开始进入正题-------------------------

Lifecycle

Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.

Lifecycle uses two main enumerations to track the lifecycle status for its associated component:

 译:Lifecycle是一个类,它保存关于组件(如activity 或fragment)生命周期状态的信息,并允许其他对象观察这个状态。

        Lifecycle使用两个主要枚举来跟踪其关联组件的生命周期状态:

Event

The lifecycle events that are dispatched from the framework and the Lifecycle class. These events map to the callback events in activities and fragments.

译:事件----从框架和lifecycle类中分派的生命周期事件。这些事件映射到activities和fragments的回调事件。 

State

The current state of the component tracked by the Lifecycle object.

 译:状态----生命周期对象跟踪的组件的当前状态。

Android Jetpack学习之Lifecycle_第1张图片

Think of the states as nodes of a graph and events as the edges between these nodes.

译: 将状态视为图的节点,将事件视为这些节点之间的线。

A class can monitor the component's lifecycle status by adding annotations to its methods. Then you can add an observer by calling the addObserver() method of the Lifecycle class and passing an instance of your observer, as shown in the following example:

 译:类可以通过向其方法添加注解来监听lifecycle组件的状态。然后你可以通过调用Lifecycle类的addObserver()方法来添加一个观察者,并传递你的观察者的一个实例,如下面的例子所示:

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

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void disconnectListener() {
        ...
    }
}

myLifecycleOwner.getLifecycle().addObserver(new MyObserver());

In the example above, the myLifecycleOwner object implements the LifecycleOwner interface, which is explained in the following section.

 译:在上面的例子中,myLifecycleOwner对象实现了LifecycleOwner接口,这将在下一节中进行解释。

LifecycleOwner

LifecycleOwner is a single method interface that denotes that the class has a Lifecycle. It has one method, getLifecycle(), which must be implemented by the class. If you're trying to manage the lifecycle of a whole application process instead, see ProcessLifecycleOwner. 

 译:LifecycleOwner是一个方法接口,表示该类有一个Lifecycle。它有一个方法getLifecycle(),这个方法必须由类实现。如果您试图管理整个应用程序流程的生命周期,请参见ProcessLifecycleOwner。

This interface abstracts the ownership of a Lifecycle from individual classes, such as Fragment and AppCompatActivity, and allows writing components that work with them. Any custom application class can implement the LifecycleOwner interface. 

译:这个接口从单个类(如Fragment和AppCompatActivity)中抽象Lifecycle的所有者,并允许编写与之一起工作的组件。任何自定义应用程序类都可以实现LifecycleOwner接口。 

Components that implement LifecycleObserver work seamlessly with components that implement LifecycleOwnerbecause an owner can provide a lifecycle, which an observer can register to watch.

 译:实现LifecycleObserver的组件与实现LifecycleOwner的组件无缝地工作,因为所有者可以提供一个lifecycle,观察者可以注册该生命周期来观察。

For the location tracking example, we can make the MyLocationListener class implement LifecycleObserver and then initialize it with the activity's Lifecycle in the onCreate() method. This allows the MyLocationListener class to be self-sufficient, meaning that the logic to react to changes in lifecycle status is declared in MyLocationListenerinstead of the activity. Having the individual components store their own logic makes the activities and fragments logic easier to manage.

译: 对于位置跟踪示例,我们可以让MyLocationListener类实现LifecycleObserver,然后在onCreate()方法中初始化 Lifecycle。这允许MyLocationListener类是自给自足的,这意味着响应lifecycle 状态变化的逻辑是在MyLocationListener中声明的,而不是在activity中声明的。让各个组件存储它们自己的逻辑,可以使activities和fragments逻辑更容易管理。

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}

A common use case is to avoid invoking certain callbacks if the Lifecycle isn't in a good state right now. For example, if the callback runs a fragment transaction after the activity state is saved, it would trigger a crash, so we would never want to invoke that callback.

 译:一个常见的用例是,如果Lifecycle目前处于不好的状态,则避免调用某些回调。例如,如果回调函数在保存活动状态之后运行一个fragment 事务,它将触发崩溃,因此我们永远不会想要调用那个回调函数。

To make this use case easy, the Lifecycle class allows other objects to query the current state.

译:为了简化这个用例,Lifecycle类允许其他对象查询当前状态。 

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.getCurrentState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

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

With this implementation, our LocationListener class is completely lifecycle-aware. If we need to use our LocationListener from another activity or fragment, we just need to initialize it. All of the setup and teardown operations are managed by the class itself.

 译:通过这个实现,我们的LocationListener类是完整的lifecycle。如果我们需要使用来自另一个activity或fragment的LocationListener,我们只需要初始化它。所有的设置和拆卸操作都由类本身管理。

If a library provides classes that need to work with the Android lifecycle, we recommend that you use lifecycle-aware components. Your library clients can easily integrate those components without manual lifecycle management on the client side.

译: 如果一个库提供了需要使用Android lifecycle,我们建议您使用lifecycle组件。您的库客户端可以轻松地集成这些组件,而无需在客户端进行手动管理lifecycle。

Implementing a custom LifecycleOwner

Fragments and Activities in Support Library 26.1.0 and later already implement the LifecycleOwner interface.

If you have a custom class that you would like to make a LifecycleOwner, you can use the LifecycleRegistry class, but you need to forward events into that class, as shown in the following code example:

译:Fragments and Activities在支持库26.1.0和更高版本中已经实现了LifecycleOwner接口。如果你有一个自定义类,你想让它成为LifecycleOwner,你可以使用LifecycleRegistry类,但是你需要将事件转发到该类中,如下面的代码示例所示:

public class MyActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry lifecycleRegistry;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        lifecycleRegistry = new LifecycleRegistry(this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

    @Override
    public void onStart() {
        super.onStart();
        lifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return lifecycleRegistry;
    }
}

Best practices for lifecycle-aware components

  • Keep your UI controllers (activities and fragments) as lean as possible. They should not try to acquire their own data; instead, use a ViewModel to do that, and observe a LiveData object to reflect the changes back to the views.

 译:保持UI控制器(activities和fragments)尽可能精简。他们不应该试图获取自己的数据;相反,使用一个ViewModel来实现这一点,并观察一个LiveData对象来将更改回调给视图。

  • Try to write data-driven UIs where your UI controller’s responsibility is to update the views as data changes, or notify user actions back to the ViewModel.

 译:尝试编写数据驱动的UI,其中UI控制器的职责是在数据更改时更新视图,或者将用户操作通知回ViewModel

  • Put your data logic in your ViewModel class. ViewModel should serve as the connector between your UI controller and the rest of your app. Be careful though, it isn't ViewModel's responsibility to fetch data (for example, from a network). Instead, ViewModel should call the appropriate component to fetch the data, then provide the result back to the UI controller. 

译: 将数据逻辑放到ViewModel类中。ViewModel应该充当UI控制器和应用程序其余部分之间的连接器。不过要注意,ViewModel并不负责获取数据(例如,从网络中)。相反,ViewModel应该调用适当的组件来获取数据,然后将结果返回给UI控制器。

  • Use Data Binding to maintain a clean interface between your views and the UI controller. This allows you to make your views more declarative and minimize the update code you need to write in your activities and fragments. If you prefer to do this in the Java programming language, use a library like Butter Knife to avoid boilerplate code and have a better abstraction.

译: 使用Data Binding来维护视图和UI控制器之间的干净接口。这允许您使视图更具声明性,并最小化您需要在activities和fragments中编写的更新代码。如果您喜欢用Java编程语言来实现这一点,那么可以使用Butter Knife这样的库来避免样板代码,从而获得更好的抽象。

  • If your UI is complex, consider creating a presenter class to handle UI modifications. This might be a laborious task, but it can make your UI components easier to test.

译: 如果UI比较复杂,可以考虑创建一个presenter类来处理UI修改。这可能是一项艰巨的任务,但它可以使UI组件更容易测试。

  • Avoid referencing a View or Activity context in your ViewModel. If the ViewModel outlives the activity (in case of configuration changes), your activity leaks and isn't properly disposed by the garbage collector.

 译:避免在ViewModel中引用ViewActivity 上下文。如果ViewModel比activity活得长(在配置更改的情况下),您的activity就会泄漏,垃圾收集器也不会正确地处理它。

Use cases for lifecycle-aware components

Lifecycle-aware components can make it much easier for you to manage lifecycles in a variety of cases. A few examples are:

 译:Lifecycle-aware组件可以使您在各种情况下更容易地管理生命周期。以下是一些例子:

  • Switching between coarse and fine-grained location updates. Use lifecycle-aware components to enable fine-grained location updates while your location app is visible and switch to coarse-grained updates when the app is in the background. LiveData, a lifecycle-aware component, allows your app to automatically update the UI when your user changes locations.

译: 在粗粒度和细粒度位置更新之间切换。使用Lifecycle-aware组件,在位置应用程序可见时启用细粒度的位置更新,并在应用程序位于后台时切换到粗粒度的更新。LiveData是一个lifecycle-aware组件,允许您的应用程序在用户更改位置时自动更新UI。

  • Stopping and starting video buffering. Use lifecycle-aware components to start video buffering as soon as possible, but defer playback until app is fully started. You can also use lifecycle-aware components to terminate buffering when your app is destroyed.

译: 停止和启动视频缓冲。使用lifecycle-aware 组件尽快启动视频缓冲,但延迟播放直到应用程序完全启动。当应用程序被销毁时,还可以使用lifecycle-aware组件终止缓冲。

  • Starting and stopping network connectivity. Use lifecycle-aware components to enable live updating (streaming) of network data while an app is in the foreground and also to automatically pause when the app goes into the background.

译: 启动和停止网络连接。当应用程序位于前台时,使用lifecycle-aware组件可以实时更新(流)网络数据,当应用程序进入后台时,还可以自动暂停。

  • Pausing and resuming animated drawables. Use lifecycle-aware components to handle pausing animated drawables when while app is in the background and resume drawables after the app is in the foreground.

译:暂停并恢复动画绘制。当应用程序在后台时,使用lifecycle-aware组件来处理动画绘制的暂停;当应用程序在前台时,使用生命周期感知组件来恢复绘制。 

Handling on stop events

When a Lifecycle belongs to an AppCompatActivity or Fragment, the Lifecycle's state changes to CREATEDand the ON_STOP event is dispatched when the AppCompatActivity or Fragment's onSaveInstanceState() is called.

译:当一个Lifecycle属于AppCompatActivity或Fragment时,当调用AppCompatActivity或Fragment的onSaveInstanceState()时,生命周期的状态更改为CREATED, ON_STOP事件被分派。 

When a Fragment or AppCompatActivity's state is saved via onSaveInstanceState(), it's UI is considered immutable until ON_START is called. Trying to modify the UI after the state is saved is likely to cause inconsistencies in the navigation state of your application which is why FragmentManager throws an exception if the app runs aFragmentTransaction after state is saved. See commit() for details.

译: 当通过onSaveInstanceState()保存 Fragment或AppCompatActivity的状态时,它的UI被认为是不可变的,直到调用ON_START。试图在保存状态后修改UI可能会导致应用程序导航状态不一致,这就是为什么如果应用程序在保存状态后运行一个FragmentTransaction,那么FragmentManager会抛出异常。有关详细信息,请参见commit()。

LiveData prevents this edge case out of the box by refraining from calling its observer if the observer's associated Lifecycle isn't at least STARTED. Behind the scenes, it calls isAtLeast() before deciding to invoke its observer.

 译:LiveData通过避免在至少没有启动观察者的关联Lifecycle的情况下调用它的观察者来防止这种情况的发生。在幕后,它在决定调用其观察者之前调用isAtLeast()

Unfortunately, AppCompatActivity's onStop() method is called after onSaveInstanceState(), which leaves a gap where UI state changes are not allowed but the Lifecycle has not yet been moved to the CREATED state.

译: 不幸的是,AppCompatActivity的onStop()方法是在onSaveInstanceState()之后调用的,这就留下了一个缺口,UI状态更改是不允许的,但是Lifecycle没有移动到 CREATED 状态。

To prevent this issue, the Lifecycle class in version beta2 and lower mark the state as CREATED without dispatching the event so that any code that checks the current state gets the real value even though the event isn't dispatched until onStop() is called by the system.

译: 为了防止这个问题,版本beta2中的Lifecycle类将CREATED状态标记为未调度事件,从而使任何检查当前状态的代码都能得到真正的值,即使直到系统调用onStop()才会分派事件。

Unfortunately, this solution has two major problems:

译:不幸的是,这个解决方案有两个主要问题:

  • On API level 23 and lower, the Android system actually saves the state of an activity even if it is partially covered by another activity. In other words, the Android system calls onSaveInstanceState() but it doesn't necessarily call onStop(). This creates a potentially long interval where the observer still thinks that the lifecycle is active even though its UI state can't be modified.

译: 在API级别23或更低时,Android系统实际上保存了一个activity的状态,即使它被另一个activity部分覆盖。换句话说,Android系统调用onSaveInstanceState(),但它不一定调用onStop()。这就创建了一个潜在的很长的间隔,在这个间隔中,观察者仍然认为生命周期是活动的,即使它的UI状态不能被修改。

  • Any class that wants to expose a similar behavior to the LiveData class has to implement the workaround provided by Lifecycle version beta 2 and lower.

译: 任何想要向LiveData类公开类似行为的类都必须实现Lifecycle version beta 2或更低版本提供的解决方案。

Note: To make this flow simpler and provide better compatibility with older versions, starting at version 1.0.0-rc1Lifecycle objects are marked as CREATED and ON_STOP is dispatched when onSaveInstanceState() is called without waiting for a call to the onStop() method. This is unlikely to impact your code but it is something you need to be aware of as it doesn't match the call order in the Activity class in API level 26 and lower.

注意:为了使这个流程更简单,并提供与旧版本更好的兼容性,从版本1.0.0-rc1开始,Lifecycle对象被标记为CREATED,当调用onSaveInstanceState()而不需要等待对onStop()方法的调用时,ON_STOP被分派。这不大可能影响您的代码,但是您需要注意,因为它与API级别26或更低的Activity类中的调用顺序不匹配。

Additional resources

To learn more about handling lifecycles with lifecycle-aware components, consult the following additional resources. 

译: 要了解关于使用lifecycle-aware组件处理lifecycles的更多信息,请参考以下附加资源。

Samples

  • Android Architecture Components Basic Sample
  • Sunflower, a demo app demonstrating best practices with Architecture Components

Codelabs

  • Android Lifecycle-aware components

Blogs

  • Introducing Android Sunflower

 

你可能感兴趣的:(android,jetpack)