Android Jetpack系列之Lifecycle组件(一篇文章掌握Lifecycle)

Lifecycle是什么?

Lifecycle是一个Android生命周期管理的组件,在Android中,activity和fragment都具备它们本身的生命周期,对于android开发来讲,界面的生命周期对咱们来讲是很重要的,处理很差的话就会出现内存泄漏的问题。在android开发中,不少功能的实现都须要在不一样的生命周期中进行相应操做的调用,好比说地图,定位须要在onStart中执行start操做,在onStop中执行stop操做;还有播放器须要在onStart中的进行链接,在onStop中进行中断链接的操做。若是咱们忘记了在onStop或者onDestory中释放资源,那么就会致使内存泄漏的问题。java

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

Kotlin代码:git

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代码:ide

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文档中的一个图片来讲明ui

lifecycle-states.png

LifeCycleOwner也是一个接口,这个接口只有getLifeCycle一个方法。用于标志它的实现类是具备生命周期的类。在26.0.1版本后的support库中的Activity、Fragment都实现了LifeCycleOwner接口。因此一般的状况下咱们不须要本身去实现LifecycleOwner,咱们只要去实现lifecycleObserver就能够了。this

Lifecycle如何使用

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

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(上下文,初始化定位的须要)。3d

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的使用,最后但愿你们都能一块儿进步。

相关文章
相关标签/搜索