Lifecycle是什么?

Lifecycle是一个Android生命周期管理的组件,在Android中,activity和fragment都具有它们自己的生命周期,对于android开发来说,界面的生命周期对我们来说是很重要的,处理不好的话就会出现内存泄漏的问题。在android开发中,很多功能的实现都需要在不同的生命周期中进行相应操作的调用,比如说地图,定位需要在onStart中执行start操作,在onStop中执行stop操作;还有播放器需要在onStart中的进行连接,在onStop中进行中断连接的操作。如果我们忘记了在onStop或者onDestory中释放资源,那么就会导致内存泄漏的问题。

为了更加清楚的了解Lifecycle和传统生命周期管理的区别,我把Google中的示例代码放上,让大家更好的理解Lifecycles

Kotlin代码:

internal class MyLocationListener(        private val context: Context,        private val callback: (Location) -> Unit) {    fun start() {        // connect to system location service    }    fun stop() {        // disconnect from system location service    }}class MyActivity : AppCompatActivity() {    private lateinit var myLocationListener: MyLocationListener    override fun onCreate(...) {        myLocationListener = MyLocationListener(this) { location ->            // update UI        }    }    public override fun onStart() {        super.onStart()        myLocationListener.start()        // manage other components that need to respond        // to the activity lifecycle    }    public override fun onStop() {        super.onStop()        myLocationListener.stop()        // manage other components that need to respond        // to the activity lifecycle    }}

java代码:

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    }}

这段代码在Android开发中是标准的实例,这样的话在各个生命周期的方法中会有大量的代码,例如onStart()和onStop(),这样使他们难以维护。

Lifecycle介绍

Lifecycle组件包括LifecycleOwner、LifecycleObserver。LifeCyclerObserver是我们要实现的具有生命周期感知的类的需要实现的接口,这个接口没有任何方法。在这个类中我们通过注解来表明函数在LifeCycleOwner的哪个生命周期的时候执行。实现了LifecycleObserver 接口的类,可以在方法上添加注解来监视其组件以来的UI界面的生命周期,可以通过调用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());

看到这里,大家没有理解不用急,后面会有一个完整的功能来演示使用Lifecycle。在上面说到了OnLifecycleEvent注解中(Lifecycle.Event的状态,为了更好的理解,我用Google文档中的一个图片来说明

LifeCycleOwner也是一个接口,这个接口只有getLifeCycle一个方法。用于标志它的实现类是具有生命周期的类。在26.0.1版本后的support库中的Activity、Fragment都实现了LifeCycleOwner接口。所以通常的情况下我们不需要自己去实现LifecycleOwner,我们只要去实现lifecycleObserver就可以了。

Lifecycle如何使用

下面我们会用一个获取定位的案例来演示Lifecycle如何使用,首先我们先建立一个BoundLocationManager的类

public class BoundLocationManager {    public static void bindLocationListenerIn(LifecycleOwner lifecycleOwner,                                              LocationListener listener, Context context) {        new BoundLocationListener(lifecycleOwner, listener, context);    }    @SuppressWarnings("MissingPermission")    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);        }        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)        void addLocationListener() {            mLocationManager =                    (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mListener);            Log.d("BoundLocationMgr", "Listener added");            // 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;            Log.d("BoundLocationMgr", "Listener removed");        }    }}

BoundLocationListener实现了LifecycleObserver接口,并在构造函数中需要传入LifecycleOwner(调用BoundLocationManager的Activity或者fragment),LocationListener(定位改变的监听),Context(上下文,初始化定位的需要)。

addLocationListener()方法上面添加了注解@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)的意思是addLocationListener()只有在LifecycleOwner(即Activity或者fragment)的生命周期为onResume()的时候才会执行

removeLocationListener()方法上面添加了注解 @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)的意思是removeLocationListener()只有在LifecycleOwner(即Activity或者fragment)的生命周期为onPause()的时候才会执行

也就是BoundLocationListener这个类可以监听Activity或者fragment的生命周期并自动执行其生命周期锁对应的方法。

还有一点需要注意的:在BoundLocationListener构造方法中 lifecycleOwner.getLifecycle().addObserver(this),只有加上这句代码,BoundLocationListener才会检测其Activity或者fragmeng的生命周期。

那么我们在Activity中应该如何使用呢?其实很简单,只需要在Activity或者fragmeng中添加一句代码就可以了

private void bindLocationListener() {    BoundLocationManager.bindLocationListenerIn(this, mGpsListener, getApplicationContext());}

看到这里,相信大家对Lifecycle的使用方式已经有了自己的了解,使用Lifecyle可以让我们更好的去管理Activity或者fragment的生命周期,而且极大简化了Activity或者fragment中的代码,并且使我们出现内存泄漏的概率大大的降低了。下面我会放出Activity中的完整代码

public class LocationActivity extends AppCompatActivity {    private static final int REQUEST_LOCATION_PERMISSION_CODE = 1;    private LocationListener mGpsListener = new MyLocationListener();    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,            @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, 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());    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.location_activity);        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();        }    }    private class MyLocationListener implements LocationListener {        @Override        public void onLocationChanged(Location location) {            TextView textView = findViewById(R.id.location);            textView.setText(location.getLatitude() + ", " + location.getLongitude());        }        @Override        public void onStatusChanged(String provider, int status, Bundle extras) {        }        @Override        public void onProviderEnabled(String provider) {            Toast.makeText(LocationActivity.this,                    "Provider enabled: " + provider, Toast.LENGTH_SHORT).show();        }        @Override        public void onProviderDisabled(String provider) {        }    }}

Activity的布局文件里面只有一个TextView,具体的代码就省略了。

如何自定义LifecycleOwner?

在上文中说过在26.0.1版本后的support库中的Activity、Fragment都实现了LifeCycleOwner接口,那么我们之前版本的Activity、Fragment也想使用Lifecycle应该怎么做?这样的话就需要我们自定义LifecycleOwner,其实自定义LifecycleOwner很简单,只需要让你的类实现LifecycleOwner 接口并在其相应的生命周期中添加几句代码就可以了。

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

以上就是Lifecycle的使用方式,Lifecycle的使用方式很简单,相信大家看到这里也基本上掌握了Lifecycle,后面将会讲解ViewModel和LiveData的使用,最后希望大家都能一起进步。

更多相关文章

  1. Android(安卓)匿名共享内存C++接口分析
  2. Android截图功能实现
  3. Android应用层源码阅读笔记--Application
  4. Android(安卓)webview加载html页面根据点击确定选中的控件
  5. Android的MediaPlayer架构介绍
  6. 一看就懂的Android(安卓)APP开发入门教程
  7. Android如何完全调试framework层代码
  8. Android(安卓)Zip文件解压缩代码
  9. Android(安卓)教程之实现动作感应技术

随机推荐

  1. mysql CURD常用操作及预处理机制
  2. PHP基础知识:命名空间的使用、自动加载器
  3. 轻量级流程图控件GoJS最新版本v2.1.35发
  4. Oracle OCP 19c 认证1Z0-083考试题库(第4
  5. 888. 公平的糖果棒交换
  6. 窗口函数更新
  7. Oracle OCP 19c 认证1Z0-083考试题库(第5
  8. 混合加密应用方案
  9. 虚拟机常见的网络类型有哪些?linux运维学
  10. 1216CSS优先级