国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

用生命周期感知組件處理生命周期

acrazing / 971人閱讀

摘要:生命周期感知組件會(huì)執(zhí)行操作來響應(yīng)另一個(gè)組件如和的生命周期狀態(tài)的改變。使用兩個(gè)主要枚舉來追蹤其關(guān)聯(lián)組件的生命周期狀態(tài)從和類中分發(fā)的生命周期事件,這些事件映射到和的回調(diào)事件中。

生命周期感知組件會(huì)執(zhí)行操作來響應(yīng)另一個(gè)組件(如 activity 和 fragment)的生命周期狀態(tài)的改變。這些組件可以幫助你生成組織性更好、更輕量級(jí)、更易于維護(hù)的代碼。

一個(gè)常見的模式是在 activity 和 fragment 的生命周期方法中實(shí)現(xiàn)依賴組件的動(dòng)作。但是,這種模式會(huì)導(dǎo)致代碼的組織不良以及錯(cuò)誤的擴(kuò)散。通過使用生命周期感知組件,可以將依賴組件的代碼從生命周期方法中轉(zhuǎn)移到組件本身。

android.arch.lifecycle 包提供了一些類和接口,讓你可以構(gòu)建生命周期感知組件,這些組件可以根據(jù)活動(dòng)或片段的當(dāng)前生命周期狀態(tài)自動(dòng)調(diào)整自己的行為。

注意:要將?android.arch.lifecycle?包導(dǎo)入到你的 Android 項(xiàng)目中, 請(qǐng)參閱?adding components to your project。

Android Framework 中定義的大多數(shù)應(yīng)用程序組件都附帶有生命周期。生命周期由操作系統(tǒng)或在你的進(jìn)程中運(yùn)行的框架代碼進(jìn)行管理。它們是 Android 工作的核心,你的應(yīng)用程序必須尊重它們。不這樣做可能會(huì)觸發(fā)內(nèi)存泄漏,甚至導(dǎo)致應(yīng)用程序崩潰。

想象一下,我們有一個(gè)在屏幕上顯示設(shè)備位置的 Activity 。常見的實(shí)現(xiàn)可能如下所示:

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

即使這個(gè)示例看起來不錯(cuò),但是在真實(shí)應(yīng)用中,你最終會(huì)有太多的調(diào)用來管理UI和其他組件,以響應(yīng)當(dāng)前的生命周期狀態(tài)。 管理多個(gè)組件會(huì)在生命周期方法中放置大量代碼,例如 onStart() 和 onStop(),這使得維護(hù)變得困難。

而且,組件在 activity 或 fragment 被停止之前啟動(dòng)是無法保證的。如果我們執(zhí)行一個(gè)長時(shí)間運(yùn)行的操作,比如在 onStart() 進(jìn)行一些配置檢查,則尤其如此。這會(huì)導(dǎo)致一種競(jìng)速的狀況,這種狀況是 onStop() 方法在 onStart() 之前結(jié)束,使組件存活的時(shí)間比他需要的時(shí)間更長。

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, location -> {
            // update UI
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        Util.checkUserStatus(result -> {
            // what if this callback is invoked AFTER activity is stopped?
            if (result) {
                myLocationListener.start();
            }
        });
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
    }
}

android.arch.lifecycle 包提供的類和接口可以幫助你以彈性和獨(dú)立的方式解決這些問題。

Lifecycle

Lifecycle 是一個(gè)類,它保存組件(如 activity 或 fragment)的生命周期狀態(tài)信息,并允許其他對(duì)象觀察此狀態(tài)。

Lifecycle 使用兩個(gè)主要枚舉來追蹤其關(guān)聯(lián)組件的生命周期狀態(tài):

Event

?從 framework 和 Lifecycle 類中分發(fā)的生命周期事件,這些事件映射到 activity 和 fragment 的回調(diào)事件中。

State

?Lifecycle 對(duì)象追蹤的組件的當(dāng)前狀態(tài)。

把 states 看作圖形的節(jié)點(diǎn),events 看作這些節(jié)點(diǎn)的邊。

一個(gè)類可以通過給它的方法添加注解來監(jiān)聽組件的生命周期,然后,你可以通過調(diào)用 Lifecycle 類的 addObserver() 方法,傳遞一個(gè)觀察者實(shí)例來添加一個(gè)觀察者,如下示例所示:

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());

在上面的示例中,myLifecycleOwner 對(duì)象實(shí)現(xiàn)了 LifecycleOwner 接口,下一節(jié)會(huì)對(duì)其進(jìn)行解釋。

LifecycleOwner

LifecycleOwner是一個(gè)表示該類有一個(gè) Lifecycle 的單方法接口。它有一個(gè)必須被該類實(shí)現(xiàn)的 getLifecycle() 方法。如果你試圖去管理整個(gè)應(yīng)用程序進(jìn)程的生命周期,請(qǐng)參閱 ProcessLifecycleOwner。

這個(gè)接口從各個(gè)類(如 Fragment 和 AppCompatActivity)提取 Lifecycle 的所有權(quán),并允許編寫與它們一起工作的組件。任何自定義的應(yīng)用程序類都可以實(shí)現(xiàn) LifecycleOwner 接口。

實(shí)現(xiàn) LifecycleObserver 的組件與實(shí)現(xiàn) LifecycleOwner的組件無縫協(xié)作,因?yàn)?owner 可以提供 observer 可以注冊(cè)的生命周期。

對(duì)位置追蹤示例來說,我們可以讓 MyLocationListener 類實(shí)現(xiàn) LifecycleObserver,然后 在 onCreate() 方法中 用 activity 的 Lifecycle 來初始化它。這允許 MyLocationListener 類自給自足,意味著對(duì)生命周期狀態(tài)的變化做出反應(yīng)的邏輯是在
MyLocationListener 而不是 activity 中聲明的。讓各個(gè)組件存儲(chǔ)自己的邏輯使得 activity 和 fragment 的邏輯更容易管理。

class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}

一個(gè)常見的用例是,如果現(xiàn)在 Lifecycle 不在一個(gè)好的狀態(tài),那么避免調(diào)用某些 callback。例如,如果 callback 在 activity 狀態(tài)被保存之后執(zhí)行一個(gè) fragment 事務(wù),會(huì)觸發(fā)崩潰,所以我們絕對(duì)不會(huì)調(diào)用該 callback。

為了簡(jiǎn)化這個(gè)用例,Lifecycle 類允許其他對(duì)象查詢當(dāng)前狀態(tài)。

class MyLocationListener implements LifecycleObserver {
    private boolean enabled = false;
    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() {
        if (enabled) {
           // connect
        }
    }

    public void enable() {
        enabled = true;
        if (lifecycle.getCurrentState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() {
        // disconnect if connected
    }
}

通過這個(gè)實(shí)現(xiàn),我們的 LocationListener 類是完全生命周期感知的。如果我們需要從其他 activity 或 fragment 中使用我們的 LocationListener,我們只需要初始化它。所有的設(shè)置和刪除操作都是由類自身管理。

如果一個(gè)庫提供了需要使用 Android 生命周期工作的類,我們建議你使用生命周期感知組件。庫客戶端可以輕松地集成這些組件,而無須在客戶端進(jìn)行手動(dòng)生命周期管理。

實(shí)現(xiàn)一個(gè)自定義的 LifecycleOwner

26.1.0 及更高版本的 Support Library 中的 Fragments and Activities 已經(jīng)實(shí)現(xiàn)了 LifecycleOwner 接口。

如果你有一個(gè)想要作為 LifecycleOwner 的自定義類,你可以使用 LifecycleRegistry 類,但是你需要將事件轉(zhuǎn)發(fā)到該類中,如下代碼所示:

public class MyActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry mLifecycleRegistry;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mLifecycleRegistry = new LifecycleRegistry(this);
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

    @Override
    public void onStart() {
        super.onStart();
        mLifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}
生命周期感知組件的最佳實(shí)踐

保持 UI 控制器盡可能精簡(jiǎn),它們不應(yīng)該試圖獲取自己的數(shù)據(jù),作為替代,使用 ViewModel 來做到這一點(diǎn),并觀察一個(gè) LiveData 對(duì)象,將變化反映給視圖。

嘗試編寫數(shù)據(jù)驅(qū)動(dòng)的 UI,該 UI 的 UI 控制器的職責(zé)是在數(shù)據(jù)變化時(shí)更新視圖,或者將用戶操作通知給ViewModel。

把數(shù)據(jù)邏輯放在 ViewModel 類中, ViewModel 應(yīng)該充當(dāng) UI 控制器和應(yīng)用程序其他部分的連接器。但是要小心,獲取數(shù)據(jù)(例如從網(wǎng)絡(luò))并不是 ViewModel 的職責(zé),作為替代, ViewModel 應(yīng)該調(diào)用適當(dāng)?shù)慕M件來獲取數(shù)據(jù),然后將結(jié)果提供給 UI 控制器。

使用 Data Binding 在視圖和 UI 控制器之間維護(hù)一個(gè)清爽的接口。這允許你讓視圖更具聲明性,并最大限度的減少需要在 activities 和 fragments 中寫入的更新代碼。如果你更喜歡用 Java 編程語言來實(shí)現(xiàn)這一點(diǎn),請(qǐng)使用類似 Butter Knife 的庫來避免樣板代碼,并具有更好的抽象。

如果你的 UI 很復(fù)雜,請(qǐng)考慮創(chuàng)建一個(gè) presenter 類來處理 UI 修改。這可能是一項(xiàng)艱巨的任務(wù),但它可以使 UI 組件更易于測(cè)試。

避免在 ViewModel 中引用View 或 Activity 上下文。如果 ViewModel 存活時(shí)間比 activity 更長(在配置更改的情況下),那么 activity 會(huì)泄露,并且無法被 GC 正確處理。

生命周期感知組件的用例

生命周期感知組件可以使你在各種情況下更容易管理生命周期。這里是一些例子:

在粗略和精細(xì)的位置信息更新之前切換。使用生命周期感知組件,在 location app 可見時(shí)啟用精細(xì)的位置更新,當(dāng)應(yīng)用處于后臺(tái)時(shí)切換到粗略的位置更新。LiveData 是一種生命周期感知組件,它允許應(yīng)用程序在位置改變時(shí)自動(dòng)更新 UI。

停止和啟動(dòng)視頻緩沖。使用生命周期感知組件盡快啟動(dòng)視頻緩沖,但是將播放推遲到應(yīng)用完全啟動(dòng)的時(shí)候。你也可以使用生命周期感知組件在應(yīng)用銷毀時(shí)終止緩沖。

啟動(dòng)和停止網(wǎng)絡(luò)連接。使用生命周期感知組件,在應(yīng)用處于前臺(tái)時(shí)啟動(dòng)網(wǎng)絡(luò)數(shù)據(jù)傳輸,在應(yīng)用進(jìn)入后臺(tái)時(shí)自動(dòng)暫停。

暫停和恢復(fù)動(dòng)畫繪制。使用生命周期感知組件,在應(yīng)用處于后臺(tái)時(shí)暫停動(dòng)畫繪制,當(dāng)應(yīng)用處于前臺(tái)時(shí)恢復(fù)繪制。

處理停止事件

當(dāng) Lifecycle 屬于AppCompatActivity 或 Fragment ,在 AppCompatActivity 或 Fragment 的 onSaveInstanceState() 被調(diào)用時(shí),Lifecycle 的狀態(tài)改變?yōu)镃REATED,ON_STOP 事件被分發(fā)。

當(dāng) Fragment 或 AppCompatActivity 的狀態(tài)通過 onSaveInstanceState() 保存時(shí),直到 ON_START 被調(diào)用為止,它的 UI 被認(rèn)為是不可變的。嘗試在保存狀態(tài)后修改 UI,可能會(huì)導(dǎo)致應(yīng)用的導(dǎo)航狀態(tài)不一致,這就是如果應(yīng)用程序在保存狀態(tài)后運(yùn)行 FragmentManager,F(xiàn)ragmentManager 拋出異常的原因,詳情請(qǐng)參閱 commit()。

如果 observer 關(guān)聯(lián)的 Lifecycle 的狀態(tài)至少不是 STARTED,LiveData 可以通過避免調(diào)用它的 observer 來防止這種極端情況的出現(xiàn)。在幕后,它在決定調(diào)用 observer 之前調(diào)用了 isAtLeast()。

不幸的是,AppCompatActivity 的 onStop() 方法是在 onSaveInstanceState() 之后被調(diào)用的,這會(huì)在 UI 狀態(tài)更改不被允許但 Lifecycle 還沒有移至 CREATED 狀態(tài)情況下留下空隙。

為了避免這個(gè)問題,beta2 和更低版本的 Lifecycle 類,將狀態(tài)標(biāo)記為 CREATED,而不分發(fā)事件,這樣任何檢查當(dāng)前狀態(tài)的代碼都會(huì)得到真實(shí)值,即使事件直到 onStop() 被系統(tǒng)調(diào)用才會(huì)被分發(fā)。

不幸的是,這個(gè)解決方案有兩個(gè)主要問題:

在 API 23及更低版本上,Android 系統(tǒng)實(shí)際上保存了 activity 的狀態(tài),即使它被另一個(gè) activity 部分覆蓋。換句話說,Android 系統(tǒng)調(diào)用 onSaveInstanceState(),但不一定調(diào)用 onStop()。這會(huì)產(chǎn)生一個(gè)潛在的長時(shí)間間隔,即使其 UI 狀態(tài)不能被修改,觀察者仍認(rèn)為生命周期是活動(dòng)的。

任何想要暴露類似行為給 LiveData 類的類必須實(shí)現(xiàn) beta 2以下版本 Lifecycle 提供的變通方法。

注意:為了使這個(gè)流程更簡(jiǎn)單,并提供與舊版本更好的兼容性,從 1.0.0-rc1 開始,Lifecycle 對(duì)象被標(biāo)記為CREATED ,并且在 onSaveInstanceState() 被調(diào)用時(shí)分發(fā) ON_STOP,而不等待 onStop() 方法的調(diào)用。這不太可能影響你的代碼,但你需要注意的是,這與 API 26 以下的 Activity 中的調(diào)用順序不匹配。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/70824.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<