Lifecycle是什么咆爽?
Lifecycle是一個(gè)Android生命周期管理的組件挫酿,在Android中惨缆,activity和fragment都具有它們自己的生命周期辟灰,對(duì)于android開發(fā)來說,界面的生命周期對(duì)我們來說是很重要的凯旭,處理不好的話就會(huì)出現(xiàn)內(nèi)存泄漏的問題概耻。在android開發(fā)中,很多功能的實(shí)現(xiàn)都需要在不同的生命周期中進(jìn)行相應(yīng)操作的調(diào)用罐呼,比如說地圖鞠柄,定位需要在onStart中執(zhí)行start操作,在onStop中執(zhí)行stop操作嫉柴;還有播放器需要在onStart中的進(jìn)行連接厌杜,在onStop中進(jìn)行中斷連接的操作。如果我們忘記了在onStop或者onDestory中釋放資源计螺,那么就會(huì)導(dǎo)致內(nèi)存泄漏的問題夯尽。
為了更加清楚的了解Lifecycle和傳統(tǒng)生命周期管理的區(qū)別,我把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開發(fā)中是標(biāo)準(zhǔn)的實(shí)例匙握,這樣的話在各個(gè)生命周期的方法中會(huì)有大量的代碼,例如onStart()和onStop()陈轿,這樣使他們難以維護(hù)圈纺。
Lifecycle介紹
Lifecycle組件包括LifecycleOwner秦忿、LifecycleObserver。LifeCyclerObserver是我們要實(shí)現(xiàn)的具有生命周期感知的類的需要實(shí)現(xiàn)的接口蛾娶,這個(gè)接口沒有任何方法灯谣。在這個(gè)類中我們通過注解來表明函數(shù)在LifeCycleOwner的哪個(gè)生命周期的時(shí)候執(zhí)行。實(shí)現(xiàn)了LifecycleObserver 接口的類蛔琅,可以在方法上添加注解來監(jiān)視其組件以來的UI界面的生命周期胎许,可以通過調(diào)用Lifecycle類的addObserver()方法傳遞觀察者實(shí)例來添加觀察者。
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());
看到這里揍愁,大家沒有理解不用急呐萨,后面會(huì)有一個(gè)完整的功能來演示使用Lifecycle杀饵。在上面說到了OnLifecycleEvent注解中(Lifecycle.Event的狀態(tài)莽囤,為了更好的理解,我用Google文檔中的一個(gè)圖片來說明
LifeCycleOwner也是一個(gè)接口切距,這個(gè)接口只有g(shù)etLifeCycle一個(gè)方法朽缎。用于標(biāo)志它的實(shí)現(xiàn)類是具有生命周期的類。在26.0.1版本后的support庫中的Activity谜悟、Fragment都實(shí)現(xiàn)了LifeCycleOwner接口话肖。所以通常的情況下我們不需要自己去實(shí)現(xiàn)LifecycleOwner,我們只要去實(shí)現(xiàn)lifecycleObserver就可以了葡幸。
Lifecycle如何使用
下面我們會(huì)用一個(gè)獲取定位的案例來演示Lifecycle如何使用最筒,首先我們先建立一個(gè)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實(shí)現(xiàn)了LifecycleObserver接口,并在構(gòu)造函數(shù)中需要傳入LifecycleOwner(調(diào)用BoundLocationManager的Activity或者fragment),LocationListener(定位改變的監(jiān)聽)蔚叨,Context(上下文床蜘,初始化定位的需要)。
addLocationListener()方法上面添加了注解@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)的意思是addLocationListener()只有在LifecycleOwner(即Activity或者fragment)的生命周期為onResume()的時(shí)候才會(huì)執(zhí)行蔑水。
removeLocationListener()方法上面添加了注解 @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)的意思是removeLocationListener()只有在LifecycleOwner(即Activity或者fragment)的生命周期為onPause()的時(shí)候才會(huì)執(zhí)行邢锯。
也就是BoundLocationListener這個(gè)類可以監(jiān)聽Activity或者fragment的生命周期并自動(dòng)執(zhí)行其生命周期鎖對(duì)應(yīng)的方法。
還有一點(diǎn)需要注意的:在BoundLocationListener構(gòu)造方法中 lifecycleOwner.getLifecycle().addObserver(this),只有加上這句代碼搀别,BoundLocationListener才會(huì)檢測(cè)其Activity或者fragmeng的生命周期丹擎。
那么我們?cè)贏ctivity中應(yīng)該如何使用呢?其實(shí)很簡(jiǎn)單歇父,只需要在Activity或者fragmeng中添加一句代碼就可以了
private void bindLocationListener() {
BoundLocationManager.bindLocationListenerIn(this, mGpsListener, getApplicationContext());
}
看到這里蒂培,相信大家對(duì)Lifecycle的使用方式已經(jīng)有了自己的了解,使用Lifecyle可以讓我們更好的去管理Activity或者fragment的生命周期榜苫,而且極大簡(jiǎn)化了Activity或者fragment中的代碼护戳,并且使我們出現(xiàn)內(nèi)存泄漏的概率大大的降低了。下面我會(huì)放出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的布局文件里面只有一個(gè)TextView单刁,具體的代碼就省略了灸异。
如何自定義LifecycleOwner府适?
在上文中說過在26.0.1版本后的support庫中的Activity、Fragment都實(shí)現(xiàn)了LifeCycleOwner接口肺樟,那么我們之前版本的Activity檐春、Fragment也想使用Lifecycle應(yīng)該怎么做?這樣的話就需要我們自定義LifecycleOwner么伯,其實(shí)自定義LifecycleOwner很簡(jiǎn)單疟暖,只需要讓你的類實(shí)現(xiàn)LifecycleOwner 接口并在其相應(yīng)的生命周期中添加幾句代碼就可以了。
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的使用方式很簡(jiǎn)單俐巴,相信大家看到這里也基本上掌握了Lifecycle,后面將會(huì)講解ViewModel和LiveData的使用硬爆,最后希望大家都能一起進(jìn)步欣舵。