Android Jetpack架構(gòu)組件Lifecycle+ViewModel+ LiveData

什么是Android Jetpack悼沈?

Android Jetpack是谷歌在2018年I/O開發(fā)者大會上推出的新一代組件、工具和架構(gòu)指導(dǎo),旨在加快開發(fā)者的 Android 應(yīng)用開發(fā)速度。 ——官方介紹網(wǎng)站

Android Jetpack 組件是庫的集合窘游,這些庫是為協(xié)同工作而構(gòu)建的,不過也可以單獨(dú)采用跳纳,同時利用 Kotlin 語言功能幫助您提高工作效率忍饰。可全部使用寺庄,也可混合搭配艾蓝!

Android Jetpack組件的優(yōu)勢:

Jetpack推出的主要目的是為了能夠讓開發(fā)者更加快速、方便以及高質(zhì)量的完成產(chǎn)品開發(fā)

  • 輕松管理應(yīng)用程序的生命周期斗塘,后臺任務(wù)的管理赢织,導(dǎo)航的處理等等
  • 利用Jetpack組件進(jìn)行開發(fā)可以有效減少內(nèi)存溢出、崩潰的概率馍盟,提升應(yīng)用開發(fā)的質(zhì)量

Jetpack組件主要分為四個方向:基礎(chǔ)于置,架構(gòu),行為和UI贞岭。詳情見下

Android Jetpack組件推薦的使用項(xiàng)目架構(gòu)

上面架構(gòu)組件的功能如下:

  • Activity和Fragment負(fù)責(zé)產(chǎn)品與用戶的交互
  • ViewModel作為數(shù)據(jù)的存儲和驅(qū)動
  • Resposity負(fù)責(zé)調(diào)度數(shù)據(jù)的獲劝颂骸(Room儲存本地序列化的數(shù)據(jù),Retrofit獲取遠(yuǎn)程數(shù)據(jù)的數(shù)據(jù))

ViewModel+ LiveData

ViewModel的優(yōu)點(diǎn):
  • 解決了運(yùn)行中斷和界面重建時的數(shù)據(jù)保存問題 (橫豎屏切換瞄桨,導(dǎo)致Activity銷毀并重新創(chuàng)建時话速,ViewMode仍然可以保留之前讀取到的數(shù)據(jù)不會因?yàn)锳ctivity的銷毀而丟失,這樣我們無需額外再浪費(fèi)資源去再次請求數(shù)據(jù))
  • 配合LiveData實(shí)時獲取最新數(shù)據(jù)
  • 實(shí)現(xiàn)Activity中Fragment之間的數(shù)據(jù)交互(數(shù)據(jù)共享)
  • 數(shù)據(jù)和界面的分離讲婚,使數(shù)據(jù)驅(qū)動界面 (ViewModel類被設(shè)計(jì)為通過lifecycle感知的方式存儲和管理UI相關(guān)數(shù)據(jù))
ViewModel的生命周期:
  • ViewModel對象的范圍是在獲取ViewModel時傳遞給ViewModelProvider的Lifecycle生命周期
  • ViewModel在內(nèi)存中直到Activity銷毀或Fragment被移除
  • 系統(tǒng)首次調(diào)用活動對象的onCreate()方法時尿孔,通常會請求ViewModel
  • 系統(tǒng)可能會在整個活動的整個生命周期中多次調(diào)用onCreate(),例如當(dāng)設(shè)備屏幕旋轉(zhuǎn)時
  • ViewModel從第一次請求ViewModel直到活動完成并銷毀時存在

ViewMode在其生命周期的范圍內(nèi)會一直保存在內(nèi)存中筹麸,所以橫豎屏切換 當(dāng)切換手機(jī)橫豎屏后,Activity會destroy并重新onCreate來重構(gòu)當(dāng)前界面雏婶,生命周期再次重新觸發(fā)onCreate物赶,但是ViewMode 并沒有重新執(zhí)行獲取數(shù)據(jù)的操作。

由于 ViewModel 生命周期可能長與 activity 生命周期留晚,所以為了避免內(nèi)存泄漏 Google 禁止在 ViewModel 中持有 Context 或 activity 或 view 的引用酵紫。
如果有些請求數(shù)據(jù)的情況必須用到Context告嘲,在繼承ViewMode的時候,可以改為繼承AndroidViewMode奖地,這個類會返回一個帶有Context的構(gòu)造函數(shù)橄唬。

ViewMode執(zhí)行onCleared操作,這個是ViewMode的一個回調(diào)参歹,表明當(dāng)前Activity要徹底關(guān)閉仰楚,ViewMode需要做一些回收清理的操作


LiveData

優(yōu)點(diǎn):

  • 確保UI界面的數(shù)據(jù)狀態(tài)
  • 沒有內(nèi)存泄漏,不會因?yàn)锳ctivity的不可見導(dǎo)致Crash
  • 一個存放可被觀察的數(shù)據(jù)持有類,但與一般的被觀察者不同的是犬庇,它是有生命周期感知功能僧界,解決了android開發(fā)者需要去手動處理生命周期的痛點(diǎn)。
  • 共享資源
 viewMode.getUserLiveData().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String users) {
                fragment2.setText("fragment2==\n" + users);
            }
        });

LiveData是一個observable數(shù)據(jù)持有類,LiveData是生命周期感知的臭挽,這意味著它跟隨其他應(yīng)用程序組件(如activities, fragments, or services)的生命周期捂襟。這種感知能力確保LiveData只更新處于活躍生命周期狀態(tài)的應(yīng)用程序組件
LiveData與一個Observer關(guān)聯(lián),如果觀察者的生命周期處于STARTED或RESUMED狀態(tài)欢峰,則表示觀察者處于活動狀態(tài)葬荷。LiveData只通知活躍的觀察者做更新。注冊到LiveData對象中的不活躍的觀察者則得不到數(shù)據(jù)更新的通知纽帖。

注冊一個observer并與實(shí)現(xiàn)了LifecycleOwner接口的對象配對宠漩。這種關(guān)系允許當(dāng)相應(yīng)的Lifecycle對象的狀態(tài)改變?yōu)镈ESTROYED時,觀察者被移除

利用ViewMode(配合LiveData實(shí)時獲取最新數(shù)據(jù))進(jìn)行Fragment之間的數(shù)據(jù)交互
public class OneFragment extends BaseFragment {
    @BindView(R2.id.fragment2)
    TextView fragment2;
    @Override
    protected int initLayout() {
        return R.layout.fragment_detail;

    }
    @Override
    protected void initView(View view) {
        //綁定ViewMode的selected的值抛计,當(dāng)有更新時通知DetailFragment
        SharedViewModel viewMode = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        viewMode.getUserLiveData().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String users) {
                fragment2.setText("fragment2==\n" + users);
            }
        });


    }

}


public class TwoFragment extends BaseFragment {
    @BindView(R2.id.fragment1)
    TextView fragment1;


    SharedViewModel viewMode;

    @Override
    protected void initView(View view) {
        //注意:這里ViewModelProviders.of(getActivity())這里的參數(shù)需要是Activity哄孤,而不能是Fragment,否則收不到監(jiān)聽
        viewMode = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

        fragment1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //當(dāng)點(diǎn)擊某一個item的時候吹截,更新viewmode中的selected的值
                viewMode.select("fragment1點(diǎn)擊后瘦陈,更新viewmode中的值,fragment2 里面的數(shù)據(jù)同步更新");
            }
        });
    }

    @Override
    protected void initData() {
        viewMode.getUserLiveData().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String users) {
                Log.w("TAG", "====" + users);
            }
        });

    }

    @Override
    protected int initLayout() {
        return R.layout.fragment_master;
    }
}





public class SharedViewModel extends AndroidViewModel {
    //userLiveData保存的是被選中的item的狀態(tài)或者數(shù)據(jù)
    private MutableLiveData<String> userLiveData;


    public MutableLiveData<String> getUserLiveData() {
        if (userLiveData == null) {
            Log.w("TAG", "SharedViewModel-getUserLiveData");
            userLiveData = new MutableLiveData<>();

        }
        return userLiveData;
    }

    //主要通過masterFragment進(jìn)行調(diào)用交互波俄,用來更新selected中的值
    public void select(String item) {
        userLiveData.setValue(item);
    }


    public SharedViewModel(@NonNull Application application) {
        super(application);
    }

    /**
     * 這里可以執(zhí)行一些資源釋放晨逝、數(shù)據(jù)清理的操作
     * ViewMode會執(zhí)行onCleared操作,這個是ViewMode的一個回調(diào)懦铺,
     * 表明當(dāng)前Activity要徹底關(guān)閉捉貌,ViewMode需要做一些回收清理的操作,如下代碼:
     */
    @Override
    protected void onCleared() {
        super.onCleared();

    }
}


上述代碼的邏輯很簡單冬念,OneFragment與TwoFragment并不直接進(jìn)行交互趁窃,而是各自與ViewMode進(jìn)行交互,OneFragment用來更新維護(hù)ViewMode中的數(shù)據(jù)急前,TwoFragment可以收到來自ViewMode中數(shù)據(jù)更新的通知醒陆。這樣便達(dá)到了兩個frangment之間的數(shù)據(jù)通信。

LifeCycles原理

Lifecycles是生命周期管理組件 另一組件的生命周期狀態(tài)(隨著Activity和Fragment)的變化而執(zhí)行動作裆针,support 26 以上的兼容包中的AppCompatActivity與Fragment中默認(rèn)已實(shí)現(xiàn)了LifeCycleOwner接口刨摩,保證了LiveData及ViewModel具備了生命周期感知與內(nèi)存緩存的能力寺晌。

場景使用:在平時的開發(fā)過程中,我們難免有些邏輯的執(zhí)行是和UI的生命周期相結(jié)合的澡刹,需要在特定的生命周期中執(zhí)行相應(yīng)的方法呻征,我們平時做的可能就是在View中的每個周期調(diào)用Present中獲取數(shù)據(jù)的方法,然后在調(diào)用View的回調(diào)接口更新UI罢浇,但現(xiàn)在使用Lifecycles可以使用注解和觀察的模式自動調(diào)用Observe中定義好的方法陆赋。

     //誰觀察生命周期  就注冊誰  兩個角色定義好后,需要讓他們之間建立聯(lián)系
        //獲取Lifecycle
        getLifecycle().addObserver(new LocationListener());


public class LocationListener implements LifecycleObserver {
    private static final String TAG = "TAG";

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void onActivityCreate(LifecycleOwner owner) {
        Log.w(TAG, "onActivityCreate");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onActivityDestroy(LifecycleOwner owner) {
        Log.w(TAG, "onActivityDestroy");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onActivityPause(LifecycleOwner owner) {
        Log.w(TAG, "onActivityPause");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onActivityResume(LifecycleOwner owner) {
        Log.w(TAG, "onActivityResume");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onActivityStart(LifecycleOwner owner) {
        Log.w(TAG, "onActivityStart");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onActivityStop(LifecycleOwner owner) {
        Log.w(TAG, "onActivityStop");
    }

}


Lifecycle 原理 如何感知 activity 或 fragment 生命周期

1己莺、activity 和 fragment 已經(jīng)實(shí)現(xiàn)了 LifecycleOwner
2奏甫、出現(xiàn)了一個LifecycleRegistry,是 Lifecycle 的一個實(shí)現(xiàn)類凌受。通過markState方法在onSaveInstanceState把 Lifecycle 狀態(tài)標(biāo)記為Lifecycle.State.CREATED阵子。
3、onCreate 方法里有個ReportFragment胜蛉,
4挠进、利用 fragment 的特性,綁定了一個 fragment 然后在其生命周期dispatch()方法中調(diào)用了LifecycleRegistry的handleLifecycleEvent誊册,此方法便是通知觀察者的地方领突。Lifecycle.Event,判斷執(zhí)行事件后下一個到達(dá)的狀態(tài)案怯,然后使用moveToState()中修改活動的生命周期
5君旦、通知觀察者addObserver 后,把observer維護(hù)到ObserverWithState然后裝到 map 里嘲碱。
然后通過handleLifecycleEvent方法最終遍歷map 通知 observer金砍。

偽代碼
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{

 private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

 @CallSuper
    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
        super.onSaveInstanceState(outState);
    }

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


  public void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

}

ViewModel 原理

    getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    if (!isChangingConfigurations()) {
                        getViewModelStore().clear();
                    }
                }
            }
        });


ViewModel 和 onSaveInstaceState方法區(qū)別在于:ViewModel只能保存因?yàn)榕渲酶膶?dǎo)致重建的數(shù)據(jù),但是它能保存大量和復(fù)雜的數(shù)據(jù)麦锯;onSaveInstaceState能保存配置更改導(dǎo)致重建和資源限制導(dǎo)致重建的數(shù)據(jù)恕稠,但是它只能保存少量簡單的數(shù)據(jù)。ViewModel使用SavedStateHandle能夠保存資源限制導(dǎo)致重建的數(shù)據(jù)扶欣。

根據(jù)傳入的Activity獲取鹅巍、創(chuàng)建、添加并以鍵值對保存Fragment料祠,從VIewStore的Map中或Factory的create()中獲取ViewMode
1骆捧、獲取ViewProvider:
2、獲取ViewModelStore:由前面的源碼可以知道創(chuàng)建ViewProvider時傳入兩個參數(shù):ViewModelStore 和 Factory髓绽;顯然從名字就可以看出他們的作用凑懂,F(xiàn)actory負(fù)責(zé)創(chuàng)建,ViewModelStore負(fù)責(zé)存儲

ViewModelStore內(nèi)部維護(hù)者一個Map集合保存者ViewModel對象的鍵值對

ViewModel的生命周期要比Activity長一點(diǎn)梧宫。因?yàn)樵贑omponentActivity 實(shí)現(xiàn)了的getViewModelStore 接谨,ViewModelStore在Activity重建前后能保持同一個對象就是通過NonConfigurationInstances實(shí)現(xiàn)的。

ActivityThread 里面performLaunchActivity方法里面塘匣,啟動Activity 調(diào)用了Activity的attach方法脓豪,在這個方法,將已有的NonConfigurationInstances賦值給了新的Activity對象忌卤。所以Activity 獲取到的ViewMode是同一個扫夜,
這樣NonConfigurationInstances能保證ViewModelStore在Activity重建前后是同一個對象,同時也知道為啥ViewModel的生命周期比Activity的生命周期要長一點(diǎn)

LiveData 原理驰徊,如何做到生命周期感知:

涉及到LifecycleOwner屬于另一個架構(gòu)組件 lifecycle笤闯,lifecycle原理上面已經(jīng)講述

偽代碼
   //LiveData數(shù)據(jù)可以再通過observe方法進(jìn)行數(shù)據(jù)回調(diào)的返回,如上代碼中的onChanged回調(diào)棍厂。
    //  從Livedata添加觀察者的方法 observe 開始:
        viewMode.getUsers().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String users) {
                viewmode_text.setText("viewMode獲取到的數(shù)據(jù)--" + users);
            }
        });

 public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }


第一個參數(shù)為LifecycleOwner用于提供當(dāng)前的生命周期狀態(tài)颗味,DESTROYED的時候不做任何操作。
第二個為觀察者observer牺弹,首先把observer包裝成了LifecycleBoundObserver,然后把LifecycleBoundObserver維護(hù)到mObservers里
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
mObservers是一個LinkedList結(jié)構(gòu)的容器 通過putIfAbsent方法判斷浦马,容器中此觀察者是不是已經(jīng)存在,如果存在且LifecycleOwner不同的話則拋異常张漂,LifecycleOwner相同則 return 不重復(fù)添加晶默。
LifecycleBoundObserver實(shí)現(xiàn)了LifecycleObserver,為lifecycle 的觀察者航攒,通過上文的 observe方法添加到了lifecycle觀察中磺陡,

接下來主要看LifecycleBoundObserver
通過此類持有 Livedata 的觀察者observer,當(dāng) 生命周期發(fā)生變化時 會回調(diào)onStateChanged方法漠畜,然后 Livedata 的觀察者在onStateChanged中執(zhí)行相應(yīng)的邏輯。

  @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }
    //接著執(zhí)行activeStateChanged
     void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            if (wasInactive && mActive) {
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                onInactive();
            }
            if (mActive) {
                dispatchingValue(this);
            }
        }

通過巧妙的設(shè)計(jì)實(shí)現(xiàn)了:
1盆驹、狀態(tài)沒有變化圆丹,什么也不做。
2躯喇、變?yōu)榛睿╝ctive)就是調(diào)用onActive()辫封,非活(inactive)就調(diào)用onInactive().
3、另外廉丽,變?yōu)榛畹脑捑驼{(diào)用dispatchingValue方法倦微,此方法為回調(diào)觀察者的方法

事件的通知
LiveData通過 setValue 或 postValue 方法去改變持有的數(shù)據(jù),并通知觀察者正压,最終都是調(diào)用dispatchingValue()方法:

 void dispatchingValue(@Nullable ObserverWrapper initiator) {
   ........................................
//遍歷之前注冊的觀察者
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

 private void considerNotify(ObserverWrapper observer) {
   ................................
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
     //開始通知了
        observer.mObserver.onChanged((T) mData);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欣福,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子焦履,更是在濱河造成了極大的恐慌拓劝,老刑警劉巖雏逾,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異郑临,居然都是意外死亡栖博,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門厢洞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仇让,“玉大人,你說我怎么就攤上這事躺翻∩ミ矗” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵公你,是天一觀的道長踊淳。 經(jīng)常有香客問我,道長省店,這世上最難降的妖魔是什么嚣崭? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮懦傍,結(jié)果婚禮上雹舀,老公的妹妹穿的比我還像新娘。我一直安慰自己粗俱,他們只是感情好说榆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著寸认,像睡著了一般签财。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上偏塞,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天唱蒸,我揣著相機(jī)與錄音,去河邊找鬼灸叼。 笑死神汹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的古今。 我是一名探鬼主播屁魏,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捉腥!你這毒婦竟也來了氓拼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎桃漾,沒想到半個月后坏匪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呈队,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年剥槐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宪摧。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖颅崩,靈堂內(nèi)的尸體忽然破棺而出几于,到底是詐尸還是另有隱情,我是刑警寧澤沿后,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布沿彭,位于F島的核電站,受9級特大地震影響尖滚,放射性物質(zhì)發(fā)生泄漏喉刘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一漆弄、第九天 我趴在偏房一處隱蔽的房頂上張望睦裳。 院中可真熱鬧,春花似錦撼唾、人聲如沸廉邑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛛蒙。三九已至,卻和暖如春渤愁,著一層夾襖步出監(jiān)牢的瞬間牵祟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工抖格, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诺苹,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓他挎,卻偏偏與公主長得像筝尾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子办桨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

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