Android Jetpack系列——LiveData源碼分析

本文章已授權(quán)微信公眾號郭霖(guolin_blog)轉(zhuǎn)載呈宇。

本文章主要是對LiveData進行源碼分析盟蚣,建議對著示例代碼閱讀文章铜异,示例代碼如下:

LiveDataDemo

本文章使用的是Android SDK 29的源碼分析艰垂。

定義

LiveData是一種可觀察數(shù)據(jù)存儲器類蹲蒲,它具有生命周期感知能力,遵循應(yīng)用組件(例如:Activity索赏、Fragment盼玄、Service(可以使用LifecycleService,它是實現(xiàn)了LifecycleOwner接口的Service))的生命周期潜腻,這種感知能力確保LiveData僅更新處于活躍生命周期狀態(tài)應(yīng)用組件觀察者埃儿。

如果觀察者(由Observer類表示)的生命周期處于STARTED或者RESUMED狀態(tài),那么LiveData會認為該觀察者處于活躍狀態(tài)砾赔,就會將更新通知它,而那些觀察LiveData對象而注冊的非活躍觀察者不會收到更改通知青灼。

應(yīng)用組件都實現(xiàn)了LifecycleOwner接口暴心,有了這種關(guān)系后,當(dāng)相應(yīng)的Lifecycle對象的狀態(tài)變?yōu)?strong>DESTROYED時杂拨,就會移除這些觀察者专普。

使用LiveData優(yōu)勢

  • 確保界面符合數(shù)據(jù)狀態(tài)

    LiveData遵循觀察者模式,當(dāng)生命周期狀態(tài)發(fā)生變化的時候弹沽,它就會去通知Observer對象檀夹,然后去更新界面筋粗。

  • 不會發(fā)生內(nèi)存泄露

    當(dāng)應(yīng)用組件的生命周期處于DESTROYED狀態(tài)時,就會移除這些觀察者炸渡,使其不再持有應(yīng)用組件引用娜亿。

  • 不會因Activity停止而導(dǎo)致崩潰

    如果觀察者的生命周期處于非活躍狀態(tài)(例如:返回棧中的Actvity),則它不會接受任何LiveData的事件蚌堵。

  • 不再需要手動處理生命周期

    界面組件只是觀察相關(guān)數(shù)據(jù)买决,不會停止或恢復(fù)觀察,LiveData將自動管理所有這些操作吼畏,因為它在觀察的時候可以感知相關(guān)的生命周期狀態(tài)變化督赤。

  • 數(shù)據(jù)始終保持最新狀態(tài)

    如果生命周期變?yōu)?strong>非活躍狀態(tài),它會在再次變?yōu)?strong>活躍狀態(tài)時接收最新的數(shù)據(jù)泻蚊,例如:曾經(jīng)在后臺的Activity會在返回前臺后立即接收最新的數(shù)據(jù)躲舌。

  • 適當(dāng)?shù)呐渲酶?/strong>

    如果由于配置更改(例如:設(shè)備旋轉(zhuǎn))而重新創(chuàng)建了Activity或者Fragment,它會立即接收到最新的數(shù)據(jù)性雄。

  • 共享資源

    我們可以使用單例模式繼承LiveData以封裝相關(guān)業(yè)務(wù)邏輯没卸,以便在應(yīng)用中共享它們。

使用LiveData

使用步驟如下:

  1. 通常是在ViewModel中創(chuàng)建LiveData實例以存儲某種類型的數(shù)據(jù)毅贮。
  2. 創(chuàng)建Observer對象办悟,并且實現(xiàn)它的onChanged方法,這個方法可以控制當(dāng)LiveData對象存儲的數(shù)據(jù)發(fā)生更改時要處理什么滩褥。
  3. 在大多數(shù)情況下病蛉,會在應(yīng)用組件onCreate方法觀察LiveData對象,調(diào)用LiveData對象的observer方法瑰煎,有兩個參數(shù)铺然,第一個參數(shù)是LifecycleOwner,它是一個接口酒甸,Activity魄健、FragmentLifecycleService都實現(xiàn)了這個接口插勤,第二個參數(shù)是第二步創(chuàng)建的Observer對象沽瘦,這樣就可以使Observer對象訂閱LiveData對象,以使其收到有關(guān)更改的通知农尖。

注意:請確保用于更新界面的LiveData對象存儲在ViewModel對象中析恋,而不是將其存儲在Activity或者Fragment中,原因如下:

  1. 避免Activity或者Fragment過于龐大盛卡,因為這些界面控制器只負責(zé)顯示數(shù)據(jù)助隧,不負責(zé)存儲數(shù)據(jù)狀態(tài)。
  2. LiveData實例與ActivityFragment分離開滑沧,可以使它在配置更改后繼續(xù)存在并村。

示例代碼

項目添加如下依賴:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha02'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc03'

由于我這邊用到了DataBinding巍实,所以加上如下代碼:

dataBinding {
    enabled = true
}

項目結(jié)構(gòu)如下圖:

LiveDataDemoProjectStructureDiagram.png

定義MainViewModel,并且繼承ViewModel哩牍,在該類中創(chuàng)建兩個MutableLiveData棚潦,firstContent是為了演示在主線程更新LiveData對象,secondContent是為了演示在工作線程更新LiveData對象姐叁,代碼如下:

/**
 * Created by TanJiaJun on 2019-12-22.
 */
class MainViewModel : ViewModel() {

    private val _firstContent = MutableLiveData<String>().apply {
        value = "第一個文本"
    }
    val firstContent: LiveData<String> = _firstContent

    private val _secondContent = MutableLiveData<String>().apply {
        value = "第二個文本"
    }
    val secondContent: LiveData<String> = _secondContent

    // 在主線程更新LiveData對象瓦盛,調(diào)用了MutableLiveData的setValue方法,下面會分析
    fun changeFirstContent(text: String) {
        _firstContent.value = text
    }

    // 在工作線程更新LiveData對象外潜,調(diào)用了MutableLiveData的postValue方法原环,下面會分析
    fun changeSecondContent(text: String) =
        viewModelScope.launch {
            withContext(Dispatchers.Default) {
                _secondContent.postValue(text)
            }
        }

}

定義FirstFragment,代碼如下:

/**
 * Created by TanJiaJun on 2019-12-22.
 */
class FirstFragment : Fragment(), FirstHandlers {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? =
        DataBindingUtil.inflate<FragmentFirstBinding>(
            inflater,
            R.layout.fragment_first,
            container,
            false
        )
            .also { binding ->
                // 調(diào)用了setLifecycleOwner方法处窥,下面會分析   
                binding.lifecycleOwner = this
                // 使MainViewModel與視圖綁定   
                binding.viewModel = activity?.let {
                    ViewModelProviders.of(it)[MainViewModel::class.java]
                }
                binding.handlers = this
            }
            .root

    // 點擊Button導(dǎo)航到SecondFragment
    override fun onNavigateToSecondFragmentClick(view: View) {
        (activity as MainActivity).addFragment(SecondFragment(), FRAGMENT_TAG_SECOND)
    }

}

interface FirstHandlers {

    fun onNavigateToSecondFragmentClick(view: View)

}

定義SecondFragment嘱吗,代碼如下:

/**
 * Created by TanJiaJun on 2019-12-22.
 */
class SecondFragment : Fragment(), SecondHandlers {

    private var viewModel: MainViewModel? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel = activity?.let { ViewModelProviders.of(it)[MainViewModel::class.java] }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? =
        DataBindingUtil.inflate<FragmentSecondBinding>(
            inflater,
            R.layout.fragment_second,
            container,
            false
        )
            .also {
                it.handlers = this
            }
            .root

    // 點擊第一個Button調(diào)用MainViewModel中的changeFirstContent方法,使FirstFragment中的第一個TextView的文本從”第一個文本“變成”第一個文本已改變“
    override fun onChangeFirstContentClick(view: View) {
        viewModel?.changeFirstContent(getString(R.string.first_content_changed))
    }

    // 點擊第二個Button調(diào)用MainViewModel中的changeSecondContent方法滔驾,使FirstFragment中的第二個TextView的文本從”第二個文本“變?yōu)椤钡诙€文本已改變“
    override fun onChangeSecondContentClick(view: View) {
        viewModel?.changeSecondContent(getString(R.string.second_content_changed))
    }

}

interface SecondHandlers {

    fun onChangeFirstContentClick(view: View)

    fun onChangeSecondContentClick(view: View)

}

由于我這里還同時用到了DataBinding谒麦、ViewModelKotlin協(xié)程哆致,所以我會在下面先按照官方文檔的寫法進行源碼分析绕德。

源碼分析

LiveData是一個抽象類,我們常用的主要用到MutableLiveDataMediatorLiveData這兩個子類摊阀,我們先看下LiveData的結(jié)構(gòu)圖:

LiveDataClassStructureDiagram.png

我們看下幾個常用的方法耻蛇,先看下observer方法,observer方法是用于在指定的LifecycleOwner內(nèi)將指定的觀察者添加到觀察列表中胞此,代碼如下:

// LiveData.java
// 創(chuàng)建key為Observer臣咖,value為ObserverWrapper的Map
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    // 檢查是否在主線程,如果不在主線程就會拋出異常
    assertMainThread("observe");
    // 判斷LifecycleOwner是否處于DESTROYED狀態(tài)
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // 如果是就return漱牵,不再分發(fā)
        return;
    }
    // 創(chuàng)建LifecycleBoundObserver夺蛇,對傳入的LifecycleOwner和Observer進行包裝,下面會分析這個類
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    // 把LifecycleBoundObserver存儲到SafeIterableMap酣胀,key為Observer刁赦,value為ObserverWrapper,如果是第一次存儲這個Observer闻镶,就會返回null
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    // 第一個條件是判斷是否第一次存儲這個Observer甚脉,第二個條件是判斷這個Observer是否已經(jīng)附在到LifecycleOwner
    if (existing != null && !existing.isAttachedTo(owner)) {
        // 如果不是第一次存儲這個Observer,而且已經(jīng)附在到LifecycleOwner儒溉,拋出“不能添加附加到不同的生命周期宦焦,但是是相同的Observer
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    // 再次判斷是否第一次存儲這個Observer
    if (existing != null) {
        // 如果不是第一次存儲這個Observer就return
        return;
    }
    // 調(diào)用Lifecycle的addObserver方法
    owner.getLifecycle().addObserver(wrapper);
}

SafeIterableMap是個Map发钝,它實際上是個LinkedList顿涣,并且支持在迭代期間修改波闹,但是不是線程安全LiveData用它來存儲LifecycleBoundObserver涛碑。

Lifecycle是一個抽象類精堕,它的唯一子類是LifecycleRegistry,我們看下它的addObserver方法蒲障,代碼如下:

// LifecycleRegistry.java
// 創(chuàng)建key為LifecycleObserver歹篓,value為ObserverWithState的FastSafeIterableMap
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
            new FastSafeIterableMap<>();

// 擁有此生命周期的提供者,在LifecycleOwner上只保留弱引用揉阎,所以如果有人泄露了Lifecycle對象庄撮,它們不會泄露整個Activity或者Fragment,但是這樣做也會泄露所有Listener對象毙籽,因為在所有Listener對象上保持著強引用
private final WeakReference<LifecycleOwner> mLifecycleOwner;

public LifecycleRegistry(@NonNull LifecycleOwner provider) {
    mLifecycleOwner = new WeakReference<>(provider);
    mState = INITIALIZED;
}

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 將LifecycleObserver(我們傳入的是LifecycleBoundObserver)和State包裝成ObserverWithState
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // 把ObserverWithState存儲到FastSafeIterableMap洞斯,key為LifecycleBoundObserver,value為ObserverWithState坑赡,如果是第一次存儲這個ObserverWithState,就會返回null
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    // 判斷是否第一次存儲這個ObserverWithState
    if (previous != null) {
        // 如果不是第一次存儲這個ObserverWithState就return
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    // 判斷LifecycleOwner是不是null
    if (lifecycleOwner == null) {
        // 如果是null的話,應(yīng)該立刻被銷毀赘那,快速回退
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // mState或者subling可能被重新計算
        targetState = calculateTargetState(observer);
    }

    // 判斷是不是在堆棧的頂層
    if (!isReentrance) {
        // 如果是在堆棧的頂層就執(zhí)行同步
        sync();
    }
    mAddingObserverCounter--;
}

如果是在堆棧的頂層评雌,就會調(diào)用sync方法,因此也不會在重入的時候調(diào)用這個方法螟加,我們看下這個方法徘溢,代碼如下:

// LifecycleRegistry.java
private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    // 判斷LifecycleOwner是不是null
    if (lifecycleOwner == null) {
        // 如果是null的話,拋出異常仰迁,證明這個LifecycleRegistry的LifecycleOwner已經(jīng)被垃圾回收了甸昏,改變生命周期太遲了
        throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                + "garbage collected. It is too late to change lifecycle state.");
    }
    while (!isSynced()) {
        mNewEventOccurred = false;
        // 不需要檢查eldest是不是null,因為isSynced已經(jīng)幫我們判斷了
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            // 如果ObserverWithState的state小于當(dāng)前的state徐许,就會倒序遍歷改變狀態(tài)同時通知觀察者
            backwardPass(lifecycleOwner);
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            // 如果ObserverWithState的state大于當(dāng)前的state施蜜,就會正序遍歷改變狀態(tài)同時通知觀察者
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

我們看下forwardPass方法和backwardPass方法,代碼如下:

// LifecycleRegistry.java
// 正序遍歷改變狀態(tài)同時通知觀察者
private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    // 正序遍歷mObserverMap
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            // 調(diào)用ObserverWithState的dispatchEvent方法
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}

// 倒序遍歷改變狀態(tài)同時通知觀察者
private void backwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();
    // 倒序遍歷mObserverMap
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            Event event = downEvent(observer.mState);
            pushParentState(getStateAfter(event));
            // 調(diào)用ObserverWithState的dispatchEvent方法
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

ObserverWithStateLifecycleRegistry靜態(tài)內(nèi)部類雌隅,我們看下ObserverWithStatedispatchEvent方法翻默,代碼如下:

// LifecycleRegistry.java
static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        // mLifecycleObserver為LifecycleBoundObserver
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        // 調(diào)用LifecycleBoundObserver的onStateChanged方法
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

LifecycleBoundObserverLiveData的內(nèi)部類,我們看下onStateChanged方法恰起,代碼如下:

// LiveData.java
// 這個方法判斷Lifecycle的狀態(tài)的值是否大于或等于STARTED狀態(tài)的值修械,從而判斷是否是活躍狀態(tài)
@Override
boolean shouldBeActive() {
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

@Override
public void onStateChanged(@NonNull LifecycleOwner source,
        @NonNull Lifecycle.Event event) {
    // 判斷Lifecycle是否為DESTROYED狀態(tài)
    if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
        // 如果Lifecycle是DESTROYED狀態(tài),移除觀察者检盼,并且return肯污,下面會對removeObserver方法分析
        removeObserver(mObserver);
        return;
    }
    // 如果Lifecycle不是DESTROYED狀態(tài),調(diào)用activeStateChanged方法,并且傳入shouldBeActive方法得到的布爾值
    activeStateChanged(shouldBeActive());
}

State是個枚舉蹦渣,代碼如下:

@SuppressWarnings("WeakerAccess")
public enum State {

    DESTROYED,

    INITIALIZED,

    CREATED,

    STARTED,

    RESUMED;

    // 判斷當(dāng)前state的值是否大于或等于傳入的state的值
    public boolean isAtLeast(@NonNull State state) {
        return compareTo(state) >= 0;
    }
}

我們可以看到哄芜,大于或等于STARTED的值就只有STARTEDRESUMED這兩個值了,也就是說這個方法是判斷是否為活躍狀態(tài)柬唯。

activeStateChanged方法代碼如下:

// LiveData.java
void activeStateChanged(boolean newActive) {
    // 判斷狀態(tài)是否發(fā)生變化
    if (newActive == mActive) {
        // 如果沒有發(fā)生變化就return
        return;
    }
    // 如果有發(fā)生變化认臊,立刻設(shè)置狀態(tài),這樣就不會向不活躍的觀察者發(fā)送內(nèi)容
    mActive = newActive;
    boolean wasInactive = LiveData.this.mActiveCount == 0;
    // 如果當(dāng)前狀態(tài)是活躍狀態(tài)就會加1锄奢,否則就會減1
    LiveData.this.mActiveCount += mActive ? 1 : -1;
    if (wasInactive && mActive) {
        // 如果mActiveCount從0變成1失晴,同時當(dāng)前狀態(tài)屬于活躍狀態(tài),就會調(diào)用onActive方法
        onActive();
    }
    if (LiveData.this.mActiveCount == 0 && !mActive) {
        // 如果mActiveCount從1變成0拘央,同時當(dāng)前狀態(tài)屬于不活躍狀態(tài)涂屁,就會調(diào)用onInactive
        onInactive();
    }
    if (mActive) {
        // 如果當(dāng)前狀態(tài)是活躍狀態(tài),調(diào)用dispatchingValue灰伟,并且傳入LifecycleBoundObserver
        dispatchingValue(this);
    }
}

我們看下dispatchingValue方法胯陋,代碼如下:

// LiveData.java
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    // 判斷是否正在分發(fā)
    if (mDispatchingValue) {
        // 如果正在分發(fā),將mDispatchInvalidated設(shè)為true袱箱,也就是設(shè)為分發(fā)無效遏乔,并且return
        mDispatchInvalidated = true;
        return;
    }
    // 正在分發(fā)
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        // 判斷initiator是否為null,根據(jù)上面的代碼可知发笔,這里不為null盟萨,注意一下為null的邏輯,下面在說setValue了讨、postValue捻激、getValue的時候會涉及到
        if (initiator != null) {
            // 如果initiator不為null就會調(diào)用considerNotify方法,傳入LifecycleBoundObserver
            considerNotify(initiator);
            initiator = null;
        } else {
            // 如果initiator為null就會遍歷mObservers
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                // 調(diào)用considerNotify方法
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    // 分發(fā)完畢
    mDispatchingValue = false;
}

mDispatchingValuemDispatchInvalidated這兩個變量是為了防止重復(fù)分發(fā)相同的內(nèi)容前计。

considerNotify方法代碼如下:

// LiveData.java
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
    // 判斷是否為活躍狀態(tài)
    if (!observer.mActive) {
        // 如果不是活躍狀態(tài)就return
        return;
    }
    // 在分發(fā)之前再檢查下最新的狀態(tài)是否為活躍狀態(tài)胞谭,防止出現(xiàn)改變了狀態(tài),但是我們還沒收到事件這種情況
    if (!observer.shouldBeActive()) {
        // 如果不是活躍狀態(tài)就通知不再分發(fā)
        observer.activeStateChanged(false);
        return;
    }
    // 判斷是否為最新的數(shù)據(jù)
    if (observer.mLastVersion >= mVersion) {
        // 如果是最新的數(shù)據(jù)就不再分發(fā)
        return;
    }
    // 將版本設(shè)為最新的版本
    observer.mLastVersion = mVersion;
    // 調(diào)用onChanged方法
    observer.mObserver.onChanged((T) mData);
}

onChanged方法的代碼如下:

// Observer.java
public interface Observer<T> {
    void onChanged(T t);
}

onChanged方法就是我們需要實現(xiàn)的方法男杈,我們可以在這個方法實現(xiàn)數(shù)據(jù)發(fā)生變化的時候要執(zhí)行的邏輯丈屹。

大家還記得sync這個方法嗎?如果忘記了伶棒,可以再往上面看下旺垒,這個sync方法也會被moveToState方法調(diào)用,代碼如下:

// LifecycleRegistry.java
private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    mState = next;
    // 判斷是否在同步或者是否在添加觀察者
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        // 如果正在同步或者正在添加觀察者就return
        return;
    }
    mHandlingEvent = true;
    // 調(diào)用sync方法
    sync();
    mHandlingEvent = false;
}

moveToState方法也會被handleLifecycleEvent方法調(diào)用肤无,這個方法作用是改變生命周期狀態(tài)先蒋,同時通知觀察者,如果現(xiàn)在的生命周期狀態(tài)和最近一次調(diào)用這個方法的生命周期狀態(tài)一樣的話宛渐,調(diào)用這個方法是沒有影響的竞漾,代碼如下:

// LifecycleRegistry.java
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

LifecycleRegistry對象是什么時候創(chuàng)建呢眯搭?有什么作用呢?我們的示例代碼MainActivity是繼承AppCompatActivity的业岁,AppCompatActivity繼承FragmentActivity坦仍,FragmentActivity繼承androidx.activity.ComponentActivity,我們看下androidx.activity.ComponentActivity的代碼:

// androidx.activity.ComponentActivity.java
// 創(chuàng)建LifecycleRegistry對象
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mSavedStateRegistryController.performRestore(savedInstanceState);
    // 注入ReportFragment
    ReportFragment.injectIfNeededIn(this);
    if (mContentLayoutId != 0) {
        setContentView(mContentLayoutId);
    }
}

我們看下ReportFragment部分代碼叨襟,代碼如下:

// ReportFragment.java
private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
        + ".LifecycleDispatcher.report_fragment_tag";

public static void injectIfNeededIn(Activity activity) {
    // ProcessLifecycleOwner應(yīng)該總是要正確工作,有一些Activity可能不繼承support lib的FragmentActivity幔荒,所以使用framework的Fragment
    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        // Hopefully, we are the first to make a transaction.
        manager.executePendingTransactions();
    }
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    dispatchCreate(mProcessListener);
    // 調(diào)用了dispatch方法糊闽,傳入Lifecycle.Event.ON_CREATE
    dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart() {
    super.onStart();
    dispatchStart(mProcessListener);
    // 調(diào)用dispatch方法,傳入Lifecycle.Event.ON_START
    dispatch(Lifecycle.Event.ON_START);
}

@Override
public void onResume() {
    super.onResume();
    dispatchResume(mProcessListener);
    // 調(diào)用dispatch方法爹梁,傳入Lifecycle.Event.ON_RESUME
    dispatch(Lifecycle.Event.ON_RESUME);
}

@Override
public void onPause() {
    super.onPause();
    // 調(diào)用dispatch方法右犹,傳入Lifecycle.Event.ON_PAUSE
    dispatch(Lifecycle.Event.ON_PAUSE);
}

@Override
public void onStop() {
    super.onStop();
    // 調(diào)用dispatch方法,傳入Lifecycle.Event.ON_STOP
    dispatch(Lifecycle.Event.ON_STOP);
}

@Override
public void onDestroy() {
    super.onDestroy();
    // 調(diào)用dispatch方法姚垃,傳入Lifecycle.Event.ON_DESTROY
    dispatch(Lifecycle.Event.ON_DESTROY);
    // 保證不泄露某個Activity的引用
    mProcessListener = null;
}

private void dispatch(Lifecycle.Event event) {
    Activity activity = getActivity();
    // 判斷Activity是否實現(xiàn)LifecycleRegistryOwner接口
    if (activity instanceof LifecycleRegistryOwner) {
        // 調(diào)用handleLifecycleEvent方法
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    // 判斷Activity是否實現(xiàn)LifecycleOwner接口
    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        // 判斷Lifecycle是否是LifecycleRegistry的子類
        if (lifecycle instanceof LifecycleRegistry) {
            // 調(diào)用handleLifecycleEvent方法
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

ReportFragment的作用是為了感知Activity的生命周期念链,每當(dāng)Activity的生命周期發(fā)生變化的時候,就會調(diào)用LifecycleRegistryhandleLifecycleEvent方法积糯,然后就會調(diào)用moveToState方法掂墓,最后就會調(diào)用sync方法,從而讓LiveData能感知Activity的生命周期看成,其實這也是Android Jetpack的另外一個很重要的組件Lifecycle的原理君编,同樣我們也看下Fragment的代碼:

// Fragment.java
LifecycleRegistry mLifecycleRegistry;

@Nullable FragmentViewLifecycleOwner mViewLifecycleOwner;
MutableLiveData<LifecycleOwner> mViewLifecycleOwnerLiveData = new MutableLiveData<>();

private void initLifecycle() {
    // 創(chuàng)建LifecycleRegistry對象
    mLifecycleRegistry = new LifecycleRegistry(this);
    mSavedStateRegistryController = SavedStateRegistryController.create(this);
    // 判斷當(dāng)前Android版本是否大于4.4
    if (Build.VERSION.SDK_INT >= 19) {
        mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                // 判斷當(dāng)前事件是否是ON_STOP
                if (event == Lifecycle.Event.ON_STOP) {
                    // 判斷View是否為null
                    if (mView != null) {
                        // 如果不是空的話,取消之前發(fā)布到事件隊列的任何延遲的高級別輸入事件
                        mView.cancelPendingInputEvents();
                    }
                }
            }
        });
    }
}

void performCreate(Bundle savedInstanceState) {
    // 省略部分代碼
    // 調(diào)用handleLifecycleEvent川慌,傳入Lifecycle.Event.ON_CREATE
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
    mChildFragmentManager.noteStateNotSaved();
    mPerformedCreateView = true;
    // 創(chuàng)建Fragment的View的LifecycleOwner
    mViewLifecycleOwner = new FragmentViewLifecycleOwner();
    mView = onCreateView(inflater, container, savedInstanceState);
    // 判斷View是否為null
    if (mView != null) {
        // 創(chuàng)建Fragment的View的Lifecycle
        mViewLifecycleOwner.initialize();
        // 然后通知新的LifecycleOwner的一些觀察者
        mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
    } else {
        // 判斷FragmentViewLifecycleOwner是否初始化
        if (mViewLifecycleOwner.isInitialized()) {
            // 如果View是null吃嘿,同時FragmentViewLifecycleOwner也初始化了,拋出異常
            throw new IllegalStateException("Called getViewLifecycleOwner() but "
                    + "onCreateView() returned null");
        }
        mViewLifecycleOwner = null;
    }
}

void performStart() {
    // 省略部分代碼
    // 調(diào)用onStart方法
    onStart();
    // 省略部分代碼
    // 調(diào)用LifecycleRegistry的handleLifecycleEvent方法梦重,傳入Lifecycle.Event.ON_START
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    // 判斷View是否為null
    if (mView != null) {
        // 如果View不是null兑燥,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent,傳入Lifecycle.Event.ON_START
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }
    // 省略部分代碼
}

void performResume() {
    // 省略部分代碼
    // 調(diào)用onResume方法
    onResume();
    // 省略部分代碼
    // 調(diào)用LifecycleRegistry的handleLifecycleEvent方法琴拧,傳入Lifecycle.Event.ON_RESUME
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    // 判斷View是否為null
    if (mView != null) {
        // 如果View不是null降瞳,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent,傳入Lifecycle.Event.ON_RESUME
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }
    // 省略部分代碼
}

void performPause() {
    // 省略部分代碼
    // 判斷View是否為null
    if (mView != null) {
        // 如果View不是null蚓胸,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent方法力崇,傳入Lifecycle.Event.ON_PAUSE
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    }
    // 調(diào)用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_PAUSE
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    // 省略部分代碼
    // 調(diào)用onPause方法
    onPause();
    // 省略部分代碼
}

void performStop() {
    // 省略部分代碼
    // 判斷View是否為null
    if (mView != null) {
        // 如果View不是null赢织,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent方法亮靴,傳入Lifecycle.Event.ON_STOP
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    }
    // 調(diào)用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_STOP
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    // 省略部分代碼
    // 調(diào)用onStop方法
    onStop();
    // 省略部分代碼
}

void performDestroyView() {
    // 判斷View是否為null
    if (mView != null) {
        // 如果View不是null于置,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent方法茧吊,傳入Lifecycle.Event.ON_DESTROY
        mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    }
    // 省略部分代碼
    onDestroyView();
    // 省略部分代碼
}

void performDestroy() {
    // 省略部分代碼
    // 調(diào)用LifecycleRegistry的handleLifecycleEvent方法贞岭,傳入Lifecycle.Event.ON_DESTROY
    mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    // 省略部分代碼
    // 調(diào)用onDestroy方法
    onDestroy();
    // 省略部分代碼
}

FragmentViewLifecycleOwner表示的是FragmentView生命周期,在大多數(shù)情況下搓侄,這反映了Fragment本身的生命周期瞄桨,但是Fragment的生命周期肯定會比它的View的生命周期要長。

同理讶踪,每當(dāng)Fragment的生命周期發(fā)生變化的時候芯侥,就會調(diào)用LifecycleRegistryhandleLifecycleEvent方法和FragmentViewLifecycleOwnerhandleLifecycleEvent方法,然后就會調(diào)用moveToState方法乳讥,最后就會調(diào)用sync方法柱查,從而讓LiveData能感知Fragment的生命周期。

然后我們再看下removeObserver方法云石,代碼如下:

// LiveData.java
// 這個方法要在主線程調(diào)用
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
    // 判斷是否在主線程
    assertMainThread("removeObserver");
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        // 如果是null的話就return
        return;
    }
    // 調(diào)用LifecycleBoundObserver的detachObserver方法
    removed.detachObserver();
    // 調(diào)用LifecycleBoundObserver的activeStateChanged方法唉工,并且傳入false,這個方法在上面也分析過了汹忠,這里不再贅述
    removed.activeStateChanged(false);
}

detachObserver方法的代碼如下:

// LiveData.java
@Override
void detachObserver() {
    // 調(diào)用LifecycleRegistry的removeObserver方法
    mOwner.getLifecycle().removeObserver(this);
}

removeObserver方法的代碼如下:

// LifecycleRegistry.java
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
    // 移除這個觀察者
    mObserverMap.remove(observer);
}

根據(jù)上面的代碼可知淋硝,系統(tǒng)也會幫我們調(diào)用這個方法來移除觀察者,防止發(fā)生內(nèi)存泄露宽菜。

以上就是LiveData能感知生命周期的原理谣膳。

還有一個方法也比較常用:observeForever方法,我們看下它的代碼:

// LiveData.java
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
    assertMainThread("observeForever");
    // 創(chuàng)建AlwaysActiveObserver
    AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing instanceof LiveData.LifecycleBoundObserver) {
        // 如果existing是LiveData.LifecycleBoundObserver類的實例铅乡,拋出異常
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    // 調(diào)用AlwaysActiveObserver的activeStateChanged方法参歹,并且傳入true
    wrapper.activeStateChanged(true);
}

再看下AlwaysActiveObserver的代碼:

// LiveData.java
private class AlwaysActiveObserver extends ObserverWrapper {

    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }

    // 重寫了shouldBeActive方法,并且返回true隆判,根據(jù)上面的代碼分析可知犬庇,這個方法是用來判斷是否為活躍狀態(tài),這里一直返回true侨嘀,也就是說一直保持著活躍狀態(tài)
    @Override
    boolean shouldBeActive() {
        return true;
    }
}

observeForever用于將指定的觀察者添加到觀察列表中臭挽,類似于調(diào)用observer方法,但是給定的LifecycleOwner狀態(tài)總是為活躍狀態(tài)咬腕,這意味著觀察者將永遠接收所有的事件欢峰,所以如果要停止觀察這個LiveData,就要手動調(diào)用removeObserver方法涨共。

然后我們再看下另外三個重要的方法的源碼:setValue方法纽帖、postValue方法和getValue方法,setValue方法和postValue方法是用于給LiveData設(shè)值举反,getValue方法是用于從LiveData取值懊直,代碼如下:

// LiveData.java
final Object mDataLock = new Object();

protected void postValue(T value) {
    boolean postTask;
    // 同步鎖作用于mDataLock對象
    synchronized (mDataLock) {
        // postTask用mPendingData的值是否為NOT_SET來判斷是否需要將Runnable添加到消息隊列
        postTask = mPendingData == NOT_SET;
        // 將value賦值給mPendingData
        mPendingData = value;
    }
    // 判斷是否需要將Runnable添加到消息隊列
    if (!postTask) {
        // 如果不需要將Runnable添加到消息隊列就return
        return;
    }
    // 如果需要將Runnable添加到消息隊列就調(diào)用ArchTaskExecutor的postToMainThread方法,下面會對這個方法分析
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

// setValue必須在主線程調(diào)用
@MainThread
protected void setValue(T value) {
    // 檢查是否在主線程
    assertMainThread("setValue");
    // mVersion自增
    mVersion++;
    // 將value賦值給mData
    mData = value;
    // 調(diào)用dispatchingValue方法
    dispatchingValue(null);
}

@SuppressWarnings("unchecked")
// 值為可空的對象
@Nullable
public T getValue() {
    Object data = mData;
    // 判斷mData的值是否為NOT_SET
    if (data != NOT_SET) {
        // 如果mData的值不是NOT_SET就返回這個值
        return (T) data;
    }
    // 如果mData的值為NOT_SET就返回null
    return null;
}

我們看下postToMainThread方法火鼻,代碼如下:

// ArchTaskExecutor.java
@NonNull
private TaskExecutor mDelegate;

private ArchTaskExecutor() {
    // 創(chuàng)建DefaultTaskExecutor對象
    mDefaultTaskExecutor = new DefaultTaskExecutor();
    // 將mDefaultTaskExecutor賦值給mDelegate
    mDelegate = mDefaultTaskExecutor;
}

// 獲取ArchTaskExecutor單一實例的方法室囊,使用雙重檢查鎖定(Double Check Locking雕崩,簡稱DCL)實現(xiàn)單例
@NonNull
public static ArchTaskExecutor getInstance() {
    if (sInstance != null) {
        return sInstance;
    }
    synchronized (ArchTaskExecutor.class) {
        if (sInstance == null) {
            // 調(diào)用ArchTaskExecutor的構(gòu)造方法
            sInstance = new ArchTaskExecutor();
        }
    }
    return sInstance;
}

@Override
public void postToMainThread(Runnable runnable) {
    // 調(diào)用DefaultTaskExecutor的postToMainThread方法
    mDelegate.postToMainThread(runnable);
}

ArchTaskExecutor繼承TaskExecutor,用于執(zhí)行一些公共任務(wù)融撞,我們看到postToMainThread方法是會調(diào)用DefaultTaskExecutorpostToMainThread方法盼铁,代碼如下:

// DefaultTaskExecutor.java
@Override
public void postToMainThread(Runnable runnable) {
    if (mMainHandler == null) {
        synchronized (mLock) {
            if (mMainHandler == null) {
                // 創(chuàng)建Handler,傳入的是主線程的Looper
                mMainHandler = createAsync(Looper.getMainLooper());
            }
        }
    }
    // 將runnable添加到消息隊列尝偎,runnable將在主線程中執(zhí)行
    mMainHandler.post(runnable);
}

然后我們看下傳入的RunnablemPostValueRunnable饶火,代碼如下:

// LiveData.java
final Object mDataLock = new Object();

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        // 同步鎖作用于mDataLock對象
        synchronized (mDataLock) {
            // 將mPendingData賦值給newValue
            newValue = mPendingData;
            // 將mPendingData設(shè)值為NOT_SET
            mPendingData = NOT_SET;
        }
        // 調(diào)用setValue方法,傳入newValue
        setValue((T) newValue);
    }
};

postValue方法最后是會調(diào)用setValue方法致扯,如果在主線程執(zhí)行已發(fā)布的任務(wù)之前多次調(diào)用這個方法肤寝,只會分發(fā)最后一個值,還有一點需要注意的是急前,假設(shè)先調(diào)用postValue方法,并且傳入a瀑构,然后調(diào)用setValue方法裆针,并且傳入b,那么會先設(shè)置為b寺晌,然后再設(shè)置為a世吨。

postValue方法最后還是會調(diào)用setValue方法,然后就會調(diào)用dispatchingValue方法呻征,并且傳入null耘婚,這個方法在上面也分析過了,這里大概說一下陆赋,如果傳入的是null的話沐祷,就會遍歷所有的觀察者,然后分發(fā)內(nèi)容攒岛,調(diào)用ObserveronChanged方法赖临,執(zhí)行我們的邏輯。

題外話

示例代碼中灾锯,我用到了Android Jetpack的另外一個組件:DataBinding兢榨,同時調(diào)用了ViewDataBindingsetLifecycleOwner方法,代碼如下:

// FirstFragment.kt
binding.lifecycleOwner = this

我們看下對應(yīng)的源碼:

// ViewDataBinding.java
@MainThread
public void setLifecycleOwner(@Nullable LifecycleOwner lifecycleOwner) {
    // 省略部分代碼
    mLifecycleOwner = lifecycleOwner;
    if (lifecycleOwner != null) {
        if (mOnStartListener == null) {
            mOnStartListener = new OnStartListener(this);
        }
        // 調(diào)用addObserver方法
        lifecycleOwner.getLifecycle().addObserver(mOnStartListener);
    }
    for (WeakListener<?> weakListener : mLocalFieldObservers) {
        if (weakListener != null) {
            // 調(diào)用WeakListener的setLifecycleOwner方法
            weakListener.setLifecycleOwner(lifecycleOwner);
        }
    }
}

setLifecycleOwner方法的代碼如下:

// ViewDataBinding.java
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
    mObservable.setLifecycleOwner(lifecycleOwner);
}

這里的mObservableLiveDataListener顺饮,LiveDataListener也實現(xiàn)了Observer接口吵聪,所以我們看下相關(guān)的代碼,代碼如下:

// ViewDataBinding.java
@Override
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
    LifecycleOwner owner = (LifecycleOwner) lifecycleOwner;
    LiveData<?> liveData = mListener.getTarget();
    if (liveData != null) {
        if (mLifecycleOwner != null) {
            liveData.removeObserver(this);
        }
        if (lifecycleOwner != null) {
            // 調(diào)用LiveData的observe方法
            liveData.observe(owner, this);
        }
    }
    mLifecycleOwner = owner;
}

// 根據(jù)上面分析可知兼雄,當(dāng)數(shù)據(jù)發(fā)生改變的時候就會調(diào)用onChanged方法
@Override
public void onChanged(@Nullable Object o) {
    ViewDataBinding binder = mListener.getBinder();
    if (binder != null) {
        // 通知對應(yīng)的UI更新
        binder.handleFieldChange(mListener.mLocalFieldId, mListener.getTarget(), 0);
    }
}

setLifecycleOwner方法是用于設(shè)置LifecycleOwner吟逝,用于觀察綁定中的LiveData的更改,如果LiveData位于其中一個Binding表達式中赦肋,但是沒有設(shè)置LifecycleOwner澎办,那么LiveData將不會被觀察到嘲碱,對它的更新也不會使UI發(fā)生更新。

另外我也用到了Kotlin協(xié)程局蚀,代碼如下:

// MainViewModel.kt
fun changeSecondContent(text: String) =
    viewModelScope.launch {
        withContext(Dispatchers.Default) {
            _secondContent.postValue(text)
        }
    }

viewModelScope將協(xié)程范圍綁定到ViewModel麦锯,也就是說如果ViewModel被清除的話,這個協(xié)程范圍也會被取消琅绅,在示例代碼中扶欣,MainViewModel生命周期和MainActivity的生命周期保持一致,防止在Activity銷毀后協(xié)程還在執(zhí)行更新UI的邏輯千扶,還持有著UI控件的引用料祠,導(dǎo)致內(nèi)存泄露

調(diào)用了withContext方法澎羞,并且傳入了Dispatchers.Default髓绽,也就是說使用Dispatchers.Default調(diào)度器調(diào)用指定的掛起塊,掛起直到完成妆绞,并且返回結(jié)果顺呕,其中Dispatchers.Default使用了共享的后臺線程池,也就是說調(diào)用postValue方法這段邏輯是在工作線程執(zhí)行的括饶,從而演示在工作線程去設(shè)置LiveData的值株茶,并且更新對應(yīng)的UI控件。

我的GitHub:TanJiaJunBeyond

Android通用框架:Android通用框架

我的掘金:譚嘉俊

我的簡書:譚嘉俊

我的CSDN:譚嘉俊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末图焰,一起剝皮案震驚了整個濱河市启盛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌技羔,老刑警劉巖僵闯,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異藤滥,居然都是意外死亡棍厂,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門超陆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牺弹,“玉大人,你說我怎么就攤上這事时呀≌牌” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵谨娜,是天一觀的道長航攒。 經(jīng)常有香客問我,道長趴梢,這世上最難降的妖魔是什么漠畜? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任币他,我火速辦了婚禮,結(jié)果婚禮上憔狞,老公的妹妹穿的比我還像新娘蝴悉。我一直安慰自己,他們只是感情好瘾敢,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布拍冠。 她就那樣靜靜地躺著,像睡著了一般簇抵。 火紅的嫁衣襯著肌膚如雪庆杜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天碟摆,我揣著相機與錄音晃财,去河邊找鬼。 笑死典蜕,一個胖子當(dāng)著我的面吹牛断盛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘉裤,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼郑临,長吁一口氣:“原來是場噩夢啊……” “哼栖博!你這毒婦竟也來了屑宠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤仇让,失蹤者是張志新(化名)和其女友劉穎典奉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丧叽,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡卫玖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了踊淳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片假瞬。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖迂尝,靈堂內(nèi)的尸體忽然破棺而出脱茉,到底是詐尸還是另有隱情,我是刑警寧澤垄开,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布琴许,位于F島的核電站,受9級特大地震影響溉躲,放射性物質(zhì)發(fā)生泄漏榜田。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枢劝。 院中可真熱鬧狸涌,春花似錦、人聲如沸邦鲫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庆捺。三九已至古今,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間滔以,已是汗流浹背捉腥。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留你画,地道東北人抵碟。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像坏匪,于是被迫代替她去往敵國和親拟逮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容