最近谷歌安卓团队推出一堆的组件开发架构,方便程序开发者编写更健壮,更安全,更简洁的代码,但是想要熟练地应用它们还是需要学习框架的原理。

Lifecycles的目的就是安卓组件(activities, fragments)在发生状态变化(onStart, onResume)的时候,其它的部分能够相应组件的变化。一个很常见的例子就是位置传感器要把位置实时传递到UI界面上,那么需要在activities onCreate()的状态的时候创建位置传感器,在onStart()的时候开启位置传感器,在onStop的时候停止位置传感器。

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;@Overridepublic void onCreate(...) {myLocationListener = new MyLocationListener(this, (location) -> {// update UI});}@Overridepublic void onStart() {super.onStart();myLocationListener.start();// manage other components that need to respond// to the activity lifecycle}@Overridepublic void onStop() {super.onStop();myLocationListener.stop();// manage other components that need to respond// to the activity lifecycle}
}

代码看上去没有什么问题,但是在真实的例子中,很有很多的监听需要根据状态去更新UI界面,而且有时候onStop可能出现出现在onStart完成之前,导致有些监听的不正确执行。

所以想出来Lifecycle这个框架,它会保存组件的状态信息,允许其它的对象观察这些状态。要理解这个Lifecycle框架,最好知道观察者模式是怎么回事,可以在网上找相关的例子进行查看。

比如有两个人需要知道天气预报的情况,这两个人可以用Observer表示,监听的的天气预报就是State, Owner就是管理这些State变化的。那么在activity中,owener是activity实体,state就是activity的状态,observer就是想要知道变化的对象。

从上图可以看到有五种状态,INITIALIZED, DESTROYED, CREATED, STARTED, RESUME,对象owner只需要被owner加入到观察对象就能感知这些变化,具体原理查看观察者模型。

因此,三者Owner, State, Observer只需要一一对应就可。

public class MyActivity extends Activity implements LifecycleOwner {private LifecycleRegistry mLifecycleRegistry;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mLifecycleRegistry = new LifecycleRegistry(this);mLifecycleRegistry.markState(Lifecycle.State.CREATED);}@Overridepublic void onStart() {super.onStart();mLifecycleRegistry.markState(Lifecycle.State.STARTED);}@NonNull@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}
}

Owner通过LifecycleRegistry进行注册,就可以发送状态发生变化的广播。Android中如果继承AppCompatActivity就可以获得相应的Lifecycle,所以两种方式随意选择。

package com.android.guide.archcomponents;import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;import com.android.guide.R;/*** By using lifecycle-aware components,* you can move the code of dependent components out of the lifecycle* methods and into the components themselves.** 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.*/public class LifecycleEvent extends AppCompatActivity {private static final int REQUEST_LOCATION_PERMISSION_CODE = 1;private LocationListener mGpsListener = new MyLocationListener();@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.textview);if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_LOCATION_PERMISSION_CODE);} else {bindLocationListener();}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {if (grantResults[0] == PackageManager.PERMISSION_GRANTED&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {bindLocationListener();} else {Toast.makeText(this, "This sample requires Location access", Toast.LENGTH_LONG).show();}}private void bindLocationListener() {BoundLocationManager.bindLocationListenerIn(this, mGpsListener, getApplicationContext());}private class MyLocationListener implements LocationListener {@Overridepublic void onLocationChanged(Location location) {TextView textView = findViewById(R.id.text_view);textView.setText(location.getLatitude() + ", " + location.getLongitude());}@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}@Overridepublic void onProviderEnabled(String provider) {Toast.makeText(LifecycleEvent.this, "Provider enabled: " + provider,Toast.LENGTH_SHORT).show();}@Overridepublic void onProviderDisabled(String provider) {Toast.makeText(LifecycleEvent.this, "Provider disabled: " + provider,Toast.LENGTH_SHORT).show();}}
}

编写一个LocationManager的实现,将它传递到Observer中,如果Observer监听到状态的变化,就会更新相关的UI,所以重新编写BoundLocationManager类。

package com.android.guide.archcomponents;
import android.annotation.SuppressLint;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;public class BoundLocationManager {public static void bindLocationListenerIn(LifecycleOwner lifecycleOwner,LocationListener listener, Context context) {new BoundLocationListener(lifecycleOwner, listener, context);}static class BoundLocationListener implements LifecycleObserver {private final Context mContext;private LocationManager mLocationManager;private final LocationListener mListener;public BoundLocationListener(LifecycleOwner lifecycleOwner,LocationListener listener, Context context) {mContext = context;mListener = listener;// 把这个类加进去监听相关状态的变化,同时把结果返回给传递进来的监听器。lifecycleOwner.getLifecycle().addObserver(this);}@SuppressLint("MissingPermission")@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)void addLocationListener() {mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0, 0, mListener);// Force an update with the last location, if available.Location lastLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);if (lastLocation != null) {mListener.onLocationChanged(lastLocation);}}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)void removeLocationListener() {if (mLocationManager == null) {return;}mLocationManager.removeUpdates(mListener);mLocationManager = null;}}
}

可以看到直接将mGpsListener的值传递到LocationManager中获取数据。

Lifecycle, LifecycleOwner, LifecycleObserver类讲解相关推荐

  1. Lifecycle使用及原理讲解

    Lifecycle是Google在2017年的IO大会上推出的 Android Architecture Components中的一个,这个组件的用处就是可以感知Activity的生命周期,先来看下它 ...

  2. C++ Primer 第五版 第7章类 7.1——类讲解(成员函数、非成员函数、构造函数)习题答案

    理论讲解请参考:C++ Primer 第五版 第7章类 7.1--类讲解(成员函数.非成员函数.构造函数) 目录 7.1 定义抽象数据类型习题答案 7.4&7.5 7.6&7.7 7. ...

  3. C++ Primer 第五版 第7章类 7.1——类讲解(成员函数、非成员函数、构造函数)

    习题答案请参考:C++ Primer 第五版 第7章类 7.1--类讲解(成员函数.非成员函数.构造函数)习题答案 目录 7.1 类讲解(成员函数.非成员函数.构造函数) 成员函数 this cons ...

  4. php 类自动执行方法,php类讲解8:PHP 自动加载类 __autoload() 方法

    __autoload() 在实际项目中,不可能把所有的类都写在一个 PHP 文件中,当在一个 PHP 文件中需要调用另一个文件中声明的类时,就需要通过 include 把这个文件引入.不过有的时候,在 ...

  5. MOOS-ivp 实验四 MOOS编程入门(2)MOOS类讲解

    MOOS-ivp 实验四 MOOS编程入门(2)MOOSapp类讲解 文章目录 MOOS-ivp 实验四 MOOS编程入门(2)MOOSapp类讲解 前言 一.MOOSapp父类的结构和方法 1.使用 ...

  6. php 对象 内存格式,php类讲解17:PHP 对象的存储与传输(序列化 seria

    对象的存储与传输 在实际项目应用中,有些任务在一两个页面是无法完成的,由于变量到脚本执行完毕就释放,我们本页所生成的对象想在其它页面使用时便碰到了麻烦. 如果需要将对象及其方法传递到我们想使用对象的页 ...

  7. Java中API常用类讲解

    一:基本数据类型包装类 1.1 如何完成以下需求: 需求1:我有一个数据,请问如何判断是否是int范围内的呢? int范围 -2^31 ~ 2^31-1 package com.edu.integer ...

  8. C++ vector类讲解

    今天在做一个学生类的管理系统时,由于没有用到数据库,这就需要一个可以容纳学生的容器.在网上找了一段时间,发现c++中的vector类可以较好的满足这样的要求,下面就简单的讲解一下c++中的vector ...

  9. Android Activity类讲解(一)

    --by CY[kotomifi@gmail.com] 1.protected void onCreate(Bundle savedInstanceState) { throw new Runtime ...

最新文章

  1. AngularJS - 自定义指令
  2. python学习笔记(七)——类基础
  3. JS实现将所有超链接指向同一个页面地址
  4. 使用MMS(MongoDB Monitoring Service)监控MongoDB
  5. 本周小结!(二叉树系列之四)
  6. mysql 使用gzip 压缩 文件,本地对 gzip 压缩的文件解压缩
  7. 开源表单系统|Tduck填鸭表单docker部署详细教程
  8. Visio 2007 序列号
  9. PMP培训机构哪家好,求推荐?
  10. 知网论文[全PDF下载],从此告别CAJ阅读器
  11. 错误“操作必须使用一个可更新的查询”原因及解决办法
  12. 一文看懂马尔科夫过程
  13. 从 160 万到 1.5 亿美元 ,开源软件迎来融资热潮
  14. delphi 龙年窗体 恭喜发财
  15. 全球十大资质正规外汇期货平台排行榜(最新版汇总)
  16. Eight HDU - 1043
  17. 计算机中的物理知识点总结,有关初中物理电磁波章节知识点总结
  18. 左手坐标系vs右手坐标系
  19. java08-集合框架实现超市会员管理系统
  20. chrome开发者工具_如何使用Chrome开发者工具查找性能瓶颈

热门文章

  1. 林大陈宇老师的原创高斯
  2. 「自控元件及线路」4 小功率同步电机
  3. .NET高级工程师面试经历
  4. 关于Spring体系的各种启动流程
  5. gateway官网解读(四)
  6. 阿里毕玄:阿里十年,从分布式到云时代的架构演进之路
  7. Tomcat简介、服务部署、虚拟主机配置及相关配置文件参数优化
  8. MongoDB——MongoDB的日常维护
  9. SCU - 4438 Censor
  10. kafka的基本概念和工作流程分析