您好,登錄后才能下訂單哦!
這篇文章主要介紹Android中Jetpack架構組件Lifecycle有什么用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
前言
Lifecycle是Jetpack架構組件中用來感知生命周期的組件,使用Lifecycles可以幫助我們寫出和生命周期相關更簡潔更易維護的代碼。
生命周期
生命周期這個簡單而又重要的知識相信大家早已耳熟能詳。假設我們現在有這樣一個簡單需求:
這個需求只是一個實例,在真實的開發中當然不可能有這樣的需要:
在Activity 可見的時候,我們去做一個計數功能,每隔一秒 將計數加1 ,當Activity不可見的時候停止計數,當Activity被銷毀的時候 將計數置為0
OK,So easy~ ,新建Main3Activity 編寫代碼如下所示:
public class Main3Activity extends AppCompatActivity { private static final String TAG = "Main3Activity"; int count = 0; /** * 是否計數 */ private boolean whetherToCount = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); } @Override protected void onResume() { super.onResume(); whetherToCount = true; new Thread(new Runnable() { @Override public void run() { while (whetherToCount) { try { Thread.sleep(1000); count++; Log.d(TAG, "onResume: " + count); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop: ----"); whetherToCount = false; } @Override protected void onDestroy() { super.onDestroy(); whetherToCount = false; count = 0; } }
運行結果如下所示:
符合我們的預期,你可能鄙視的看了我一眼,這樣多臃腫啊,我可是學過面向對象的人,所以你把工作放在了一個名為WorkUtil的類中
public class WorkUtil { private static final String TAG = "WorkUtil"; private boolean whetherToCount = true; private int count = 0; public void start() { new Thread(new Runnable() { @Override public void run() { while (whetherToCount) { try { Thread.sleep(1000); count++; Log.d(TAG, "start: " + count); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } public void onStop() { whetherToCount = false; } public void onDestory() { count = 0; } }
然后再activity中的生命周期中分別執行對應的方法,感覺美滋滋~
然而 ,這樣還是不夠解耦,如果方法過多的話 ,會讓view中的代碼越來越臃腫,那么 還有更好的方案嗎?這就是今天所說的Lifecycle。我們待會回過頭來再優化上面的代碼。
使用Lifecycle管理生命周期
我們通過改寫WorkUtil類來講解如何使用Lifecycle,讓WorkUtil類實現LifecycleObserver
我們通過OnLifecycleEvent注解來注明方法所執行的生命周期,如下所示:
public class WorkUtil implements LifecycleObserver { private static final String TAG = "WorkUtil"; private boolean whetherToCount = true; private int count = 0; @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void start() { new Thread(new Runnable() { @Override public void run() { while (whetherToCount) { try { Thread.sleep(1000); count++; Log.d(TAG, "start: " + count); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void onStop() { whetherToCount = false; } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) public void onDestory() { count = 0; } }
在Activity中注冊即可:
getLifecycle().addObserver(new WorkUtil());
這樣是不是簡潔多了呢,那么我們為什么可以在Activity中直接使用getLifecycle().addObserver(new WorkUtil());呢,其實使用的是LifecycleOwner.getLifecycle, LifecycleOwner是單一方法接口,表示類具有 Lifecycle,而如果activity繼承自AppcompatActivity或Fragment繼承自androidx.fragment.app.Fragment他們本身就是一個LifecycleOwner的實例,這是AndroidX庫幫我們自動完成的。
自定義LifecycleOwner
如果我們的Activity由于各種原因繼承的不是AppcompatActivity而是Activity呢
我們可以看到這個時候,就不能直接使用getLifecycle,而要自定義一個LifecycleOwner了,我們讓Activity繼承自LifecycleOwner,
使用LifecycleRegistry定義如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); lifecycleRegistry = new LifecycleRegistry(this); getLifecycle().addObserver(new WorkUtil()); }
@NonNull @Override public Lifecycle getLifecycle() { return lifecycleRegistry; }
這樣我們就實現了自定義LifecycleOwner了,不過大多數時候我們還是不需要自定義的。
優雅的檢測應用程序前后臺狀態
很多業務中我們都需要監聽應用前后臺的狀態 ,比如在前臺的時候開始緩存任務,在后臺的時候停止緩存任務,其實方法有很多,比如
使用我們上面所說的方法,監聽BaseActivity,但是都不夠優雅,如果我們想監聽所有Activty的生命周期就要使用ActivityLifecycleCallbacks,我們新建ForegroundCallbacks類實現ActivityLifecycleCallbacks
public class ForegroundCallbacks implements Application.ActivityLifecycleCallbacks { private static final String TAG = "ForegroundCallbacks"; @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { Log.d(TAG, "onActivityCreated: " + activity.getComponentName()); } @Override public void onActivityStarted(@NonNull Activity activity) { Log.d(TAG, "onActivityStarted: "+ activity.getComponentName()); } @Override public void onActivityResumed(@NonNull Activity activity) { Log.d(TAG, "onActivityResumed: "+ activity.getComponentName()); } @Override public void onActivityPaused(@NonNull Activity activity) { Log.d(TAG, "onActivityPaused: "+ activity.getComponentName()); } @Override public void onActivityStopped(@NonNull Activity activity) { Log.d(TAG, "onActivityStopped: "+ activity.getComponentName()); } @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { Log.d(TAG, "onActivitySaveInstanceState: "+ activity.getComponentName()); } @Override public void onActivityDestroyed(@NonNull Activity activity) { Log.d(TAG, "onActivityDestroyed: "+ activity.getComponentName()); } }
添加一個初始化的方法:
/** * 初始化foregroundCallbacks * * @param appApplication application */ public static ForegroundCallbacks init(AppApplication appApplication) { instance = new ForegroundCallbacks(); appApplication.registerActivityLifecycleCallbacks(instance); return instance; }
在Application中進行注冊:
ForegroundCallbacks.init(this);
運行項目日志如下:
現在我們知道肯定要在onActivityResumed和onActivityPaused兩個方法中進行判斷,但是肯定不是說進入到了resumed就是在前臺,進入到了paused就是后臺,因為我們的應用會有多個activity,只有第一個activity在前臺的時候我們才提示在前臺,只有所有activity都不可見的時候才提示在后臺,按照這種思路我們編寫對應的處理
首先定義個接口 里面回調在前臺或在后臺的方法
public interface Listener { /** * 在前臺 */ public void onBecameForeground(); /** * 在后臺 */ public void onBecameBackground(); }
定義標記位
private Runnable runnable; /** * 是否執行過onResumed */ private boolean onResumed = false; /** * 是否執行過onPaused */ private boolean onPaused = true;
@Override public void onActivityResumed(@NonNull Activity activity) { Log.d(TAG, "onActivityResumed: " + activity.getComponentName()); onPaused = false; if (runnable != null){ handler.removeCallbacks(runnable); } handler.postDelayed(runnable = new Runnable() { @Override public void run() { if (!onResumed) { listener.onBecameForeground(); onResumed = true; } } },600); } @Override public void onActivityPaused(@NonNull Activity activity) { Log.d(TAG, "onActivityPaused: " + activity.getComponentName()); onPaused = true; if (runnable != null){ handler.removeCallbacks(runnable); } handler.postDelayed(runnable = new Runnable() { @Override public void run() { if (onResumed && onPaused) { onResumed = false; listener.onBecameBackground(); } } }, 600); }
在這里我們進行延遲0.6s的原因是為了避免啟動新的activity 舊的activity頁面不可見時誤以為在后臺,不過在真實的業務場景中還是需要按照細節進行優化,在applicaton添加事件回調
ForegroundCallbacks.init(this).addListener(new ForegroundCallbacks.Listener() { @Override public void onBecameForeground() { Log.d(TAG, "onBecameForeground: 在前臺"); } @Override public void onBecameBackground() { Log.d(TAG, "onBecameBackground: 在后臺"); } });
運行程序切換到后臺 再切換回來 結果如下所示:
如此 我們就可以優雅的監聽應用前后臺切換了。
是否感受到Lifecycle的強大了呢?
以上是Android中Jetpack架構組件Lifecycle有什么用的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。