Android Architecture Components之处理生命周期
Android Architecture Components之处理生命周期
dj_归去来兮 发表于5个月前
Android Architecture Components之处理生命周期
  • 发表于 5个月前
  • 阅读 11
  • 收藏 0
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

包  android.arch.lifecycle 提供了类和接口让你构建拥有生命周期的组件--可以根据activity或者fragment的生命周期做出调整的组件。

大部分的APP组件都是在Android框架中定义的,都会有生命周期。这些生命周期过程被操作系统或者框架代码管理着。它们是Android运行的核心,你的应用必须遵守它们。不这样做可能会引起内存泄漏或者应用挂掉。

想想一下,我们有个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;

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

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

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

尽管这个示例看起来没毛病,在真实的APP开发中,你对onStart()、 onStop()方法有太多的调用,这会导致代码非常臃肿。

此外,有些组件不会在onStart()方法中就已经处于started状态了。如果我们需要在开始观察位置之前检查一些配置将会发生什么呢?有些情况是这样的:在activity停止之后,检查过程才停止,这就意味着,myLocationListener.start()的调用是在 myLocationListener.stop()调用之后,基本上永远保持连接状态。

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();
    }
}

包 android.arch.lifecycle 提供了类和接口帮助你通过富有弹性和独立的方式解决这些问题。

Lifecycle

Lifecycle 类持有关于activity或者fragment等组件的生命周期状态,允许其他对象观察这些状态。

Lifecycle 使用两个主要的枚举跟踪关联的组件的生命周期。

Event:这些生命周期事件由框架和 Lifecycle发送。这些事件与activities和fragments回调事件一 一对应。

State: Lifecycle 对象追踪的组件的当前状态。

设想state是图表中的节点,event是两个节点之间的边框线。

通过在方法上加上注解,可以让一个类监控组件的生命周期。

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是一个函数式接口,表示实现类有生命周期。只有一个方法:getLifecycle(),需要被子类实现。

这个类从个体类(activity,fragment)中抽象了生命周期的所有权,允许编写可以与它们一起工作的组件。任何一个自定义的应用类都可以实现这个接口。

针对上面的示例,我们可以使我们的MyLocationListener 类称为一个 LifecycleObserver ,然后通过 Lifecycle 的方法onCreate初始化它。

class MyActivity extends LifecycleActivity {
    private MyLocationListener myLocationListener;

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

如果当前 Lifecycle不是处在一个良好的状态,通常情况下要避免调用特定的回调方法。例如,在activity的onSaveInstance方法调用之后,调用了运行fragment事物的回调方法,将会导致奔溃,所以,我们不要去调用那个回调方法。

为了让这个方案易于使用,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.getState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

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

这个实现,我们的 LocationListener 类是有完整的生命周期。它可以不用通过管理自己的activity对自己初始化和清除工作。如果我们需要从另外一个activity或者另外一个fragment使用LocationListener ,我们只需要初始化它就行了。全部的设置和数据清除的操作全部由自己来完成。

可以和 Lifecycle 协同工作的类称为有生命周期的组件。提供与Android生命周期协同工作的类的类库推荐对外提供有生命周期的组件,以便它们的调用客户端不用手动管理生命周期,从而易于集成。

LiveData是有生命周期的组件的一个例子。将 LiveData和 ViewModel一起使用,更易于在遵循Android生命周期的情况下使用数据填充UI层。

Best practices for Lifecycles

    1 保持你的UI控制层(activities,fragments)越轻越好。它们不应该自己去取数据,相反,使用一个 ViewModel去做,并且观察 LiveData 反应到UI层上。

    2 尝试编写数据驱动UI,当数据变化时,你的UI层控制器负责更新控件,或者通知用户操作到ViewModel

    3 把数据操作逻辑放在ViewModel 类中,ViewModel 应该像UI层与其他APP组件之间的连接器。不过,要小心,获取数据(例如,从网路获取数据)并不是ViewModel 的责任。ViewModel 应该调用适当的组件去做这个工作,然后提供结果给UI层控制器。

    4 使用Data Binding在控件和控制器之间保持干净的接口。这允许在activity和fragment中,你把你的控件更声明化(声明性编程),并且更新最少的代码。

    5 如果你的UI很复杂,考虑创建一个presenter类持有UI的变化。这通常过度封装了,但是可以让UI层的测试更加容易。

    6 决不要在 ViewModel 层引用 View 或者Activity 上下文。如果ViewModel比activity的生命周期长的话,activity将会内存泄漏,不能正确的GC。

 

Addendum

Implementing LifecycleOwner in custom activities and fragments

任何一个自定义的fragment和activity都可以通过实现内建的LifecycleRegistryOwner 接口变成LifecycleOwner,而不是继承 LifecycleFragment 或者 LifecycleActivity

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

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

如果你有个自定义的想要变成 LifecycleOwner 的类,你可以使用 LifecycleRegistry 类,但是你需要转发事件到这个类中。如果他们实现了 LifecycleRegistryOwner 接口,这个事件转发对fragments,activities会自动的进行。

来自 https://developer.android.google.cn/topic/libraries/architecture/lifecycle.html

共有 人打赏支持
粉丝 14
博文 88
码字总数 31620
×
dj_归去来兮
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: