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組件包括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
LifeCycleOwner也是一個接口,這個接口只有getLifeCycle一個方法。用於標誌它的實現類是具備生命週期的類。在26.0.1版本後的support庫中的Activity、Fragment都實現了LifeCycleOwner接口。因此一般的狀況下咱們不須要本身去實現LifecycleOwner,咱們只要去實現lifecycleObserver就能夠了。this
下面咱們會用一個獲取定位的案例來演示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,具體的代碼就省略了。
在上文中說過在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的使用,最後但願你們都能一塊兒進步。