Lifecycle, LifecycleOwner, LifecycleObserver类讲解
最近谷歌安卓团队推出一堆的组件开发架构,方便程序开发者编写更健壮,更安全,更简洁的代码,但是想要熟练地应用它们还是需要学习框架的原理。
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类讲解相关推荐
- Lifecycle使用及原理讲解
Lifecycle是Google在2017年的IO大会上推出的 Android Architecture Components中的一个,这个组件的用处就是可以感知Activity的生命周期,先来看下它 ...
- C++ Primer 第五版 第7章类 7.1——类讲解(成员函数、非成员函数、构造函数)习题答案
理论讲解请参考:C++ Primer 第五版 第7章类 7.1--类讲解(成员函数.非成员函数.构造函数) 目录 7.1 定义抽象数据类型习题答案 7.4&7.5 7.6&7.7 7. ...
- C++ Primer 第五版 第7章类 7.1——类讲解(成员函数、非成员函数、构造函数)
习题答案请参考:C++ Primer 第五版 第7章类 7.1--类讲解(成员函数.非成员函数.构造函数)习题答案 目录 7.1 类讲解(成员函数.非成员函数.构造函数) 成员函数 this cons ...
- php 类自动执行方法,php类讲解8:PHP 自动加载类 __autoload() 方法
__autoload() 在实际项目中,不可能把所有的类都写在一个 PHP 文件中,当在一个 PHP 文件中需要调用另一个文件中声明的类时,就需要通过 include 把这个文件引入.不过有的时候,在 ...
- MOOS-ivp 实验四 MOOS编程入门(2)MOOS类讲解
MOOS-ivp 实验四 MOOS编程入门(2)MOOSapp类讲解 文章目录 MOOS-ivp 实验四 MOOS编程入门(2)MOOSapp类讲解 前言 一.MOOSapp父类的结构和方法 1.使用 ...
- php 对象 内存格式,php类讲解17:PHP 对象的存储与传输(序列化 seria
对象的存储与传输 在实际项目应用中,有些任务在一两个页面是无法完成的,由于变量到脚本执行完毕就释放,我们本页所生成的对象想在其它页面使用时便碰到了麻烦. 如果需要将对象及其方法传递到我们想使用对象的页 ...
- Java中API常用类讲解
一:基本数据类型包装类 1.1 如何完成以下需求: 需求1:我有一个数据,请问如何判断是否是int范围内的呢? int范围 -2^31 ~ 2^31-1 package com.edu.integer ...
- C++ vector类讲解
今天在做一个学生类的管理系统时,由于没有用到数据库,这就需要一个可以容纳学生的容器.在网上找了一段时间,发现c++中的vector类可以较好的满足这样的要求,下面就简单的讲解一下c++中的vector ...
- Android Activity类讲解(一)
--by CY[kotomifi@gmail.com] 1.protected void onCreate(Bundle savedInstanceState) { throw new Runtime ...
最新文章
- AngularJS - 自定义指令
- python学习笔记(七)——类基础
- JS实现将所有超链接指向同一个页面地址
- 使用MMS(MongoDB Monitoring Service)监控MongoDB
- 本周小结!(二叉树系列之四)
- mysql 使用gzip 压缩 文件,本地对 gzip 压缩的文件解压缩
- 开源表单系统|Tduck填鸭表单docker部署详细教程
- Visio 2007 序列号
- PMP培训机构哪家好,求推荐?
- 知网论文[全PDF下载],从此告别CAJ阅读器
- 错误“操作必须使用一个可更新的查询”原因及解决办法
- 一文看懂马尔科夫过程
- 从 160 万到 1.5 亿美元 ,开源软件迎来融资热潮
- delphi 龙年窗体 恭喜发财
- 全球十大资质正规外汇期货平台排行榜(最新版汇总)
- Eight HDU - 1043
- 计算机中的物理知识点总结,有关初中物理电磁波章节知识点总结
- 左手坐标系vs右手坐标系
- java08-集合框架实现超市会员管理系统
- chrome开发者工具_如何使用Chrome开发者工具查找性能瓶颈