【大揭秘】Android架構(gòu)組件ViewModel來龍去脈

ViewModel是google官方的MVVM架構(gòu)組件藐握,目前已經(jīng)集成到了最新的支持庫中了,是MVVM架構(gòu)的核心組件之一拉背。不懂MVVM的請看之前的文章:(一)Android官方MVVM框架實現(xiàn)組件化之整體結(jié)構(gòu)

1.ViewModel官方解釋

網(wǎng)上看到的ViewModel的博文千篇一律,實在忍不了,自己寫看了源碼寫了一篇网棍,歡迎拍磚!

ViewModel是存儲UI相關(guān)數(shù)據(jù)并不會因為旋轉(zhuǎn)而銷毀的類妇智。

最為重要的就是ViewModel具有下面的生命周期滥玷,這就是ViewModel的最可貴之處:


2.ViewModel生命周期,Activity配置變化ViewModel也不會銷毀

正因為ViewModel有如此的生命周期巍棱,所以ViewModel在MVVM可以作為數(shù)據(jù)存儲區(qū)惑畴,是連接View和Model重要組件,ViewModel的核心作用如下圖所示:


ViewModel在MVVM中的核心作用

這篇文字要弄清楚下面幾個問題:

  • 1.ViewModel是怎么創(chuàng)建的航徙?
  • 2.ViewModel是怎么存儲的如贷?
  • 3.ViewModel為什么可以實現(xiàn)旋轉(zhuǎn)屏幕不銷毀?

先放簡單講一下ViewModel的基本使用方法到踏,我們在獲取ViewModel的時候絕對不能直接使用new關(guān)鍵字去創(chuàng)建杠袱,需要使用 ViewModelProviders 去使用系統(tǒng)提供的反射方法去創(chuàng)建我們想要的ViewModel,下面是官方架構(gòu)組件android.arch.lifecycle包下面的ViewModelProviders工具類用來獲取ViewModel:

/**
 * 注解by danxx on 2018/3/31.
 * Global ViewModel Provider
 * ViewModel的創(chuàng)建不可直接new窝稿,需要使用這個{@link ViewModelProviders}才能與Activity或者
 * Fragment的生命周期關(guān)聯(lián)起來楣富!
 */
public class ViewModelProviders {

    /**
     * 通過Activity獲取可用的Application
     * 或者檢測Activity是否可用
     * @param activity
     * @return
     */
    private static Application checkApplication(Activity activity) {
        Application application = activity.getApplication();
        if (application == null) {
            throw new IllegalStateException("Your activity/fragment is not yet attached to "
                    + "Application. You can't request ViewModel before onCreate call.");
        }
        return application;
    }

    /**
     * 通過Fragment獲取Activity
     * 或者檢測Fragment是否可用
     * @param fragment
     * @return
     */
    private static Activity checkActivity(Fragment fragment) {
        Activity activity = fragment.getActivity();
        if (activity == null) {
            throw new IllegalStateException("Can't create ViewModelProvider for detached fragment");
        }
        return activity;
    }

    /**
     * 通過Fragment獲得ViewModelProvider
     * @param fragment
     * @return
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull Fragment fragment) {

        /**獲取默認的單例AndroidViewModelFactory,它內(nèi)部是通過反射來創(chuàng)建具體的ViewModel*/
        ViewModelProvider.AndroidViewModelFactory factory =
                ViewModelProvider.AndroidViewModelFactory.getInstance(
                        checkApplication(checkActivity(fragment)));
        /***
         *   利用HolderFragment來關(guān)聯(lián)生命周期并使用HolderFragment中的ViewModelStore的HashMap存儲ViewModel
         *   AndroidViewModelFactory創(chuàng)建ViewModel
         */
        return new ViewModelProvider(ViewModelStores.of(fragment), factory);
    }

    /**
     * 通過FragmentActivity獲得ViewModelProvider
     * @param activity
     * @return
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull FragmentActivity activity) {
        /**獲取默認的單例AndroidViewModelFactory伴榔,它內(nèi)部是通過反射來創(chuàng)建具體的ViewModel*/
        ViewModelProvider.AndroidViewModelFactory factory =
                ViewModelProvider.AndroidViewModelFactory.getInstance(
                        checkApplication(activity));
        /***
         *   利用HolderFragment來關(guān)聯(lián)生命周期并使用HolderFragment中的ViewModelStore的HashMap存儲ViewModel
         *   AndroidViewModelFactory創(chuàng)建ViewModel
         */
        return new ViewModelProvider(ViewModelStores.of(activity), factory);
    }

    /**
     *
     * @param fragment
     * @param factory 提供了自定義創(chuàng)建ViewModel的方法
     * @return
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull Fragment fragment, @NonNull ViewModelProvider.Factory factory) {
        //檢測Fragment 
        checkApplication(checkActivity(fragment));
        return new ViewModelProvider(ViewModelStores.of(fragment), factory);
    }

    /**
     *
     * @param activity
     * @param factory 提供了自定義創(chuàng)建ViewModel的方法
     * @return
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull FragmentActivity activity,
                                       @NonNull ViewModelProvider.Factory factory) {
        //檢測activity
        checkApplication(activity);
        return new ViewModelProvider(ViewModelStores.of(activity), factory);
    }
}


有一些解釋我已經(jīng)放在注釋里了纹蝴,有興趣的可以仔細看看。

開始創(chuàng)建使用ViewModel了:

1.在Activity中創(chuàng)建使用ViewModel:

        /**轉(zhuǎn)入Activity就行*/
        GirlsViewModel girlsViewModel =
        ViewModelProviders.of(ActivityGirls.this).get(GirlsViewModel.class);

2.在Fragment中創(chuàng)建使用ViewModel:

       /**轉(zhuǎn)入Fragment就行*/
       GirlsViewModel girlsViewModel =
       ViewModelProviders.of(FragmentGirls.this).get(GirlsViewModel.class);

3.在任意地方創(chuàng)建使用ViewModel:

      /**將context強轉(zhuǎn)成FragmentActivity就行*/
      GirlsViewModel girlsViewModel =
      ViewModelProviders.of((FragmentActivity) context).get(GirlsViewModel.class);

ViewModel 的存在是依賴 Activity 或者 Fragment的潮梯,不管你在什么地方獲取ViewModel 骗灶,只要你用的是相同的Activity 或者 Fragment,那么獲取到的ViewModel將是同一個 (前提是key值是一樣的)秉馏,所以ViewModel 也具有數(shù)據(jù)共享的作用耙旦!

一、ViewModel是怎么創(chuàng)建的?

上面創(chuàng)建ViewModel鏈式調(diào)用分解為下面兩步:

        /*****第一步:根據(jù)Activity或者Fragment獲得ViewModelProvider****/
        ViewModelProvider viewModelProvider = ViewModelProviders.of(ActivityGirls.this);

        /*****第二步:使用ViewModelProvider反射創(chuàng)建需要的ViewModel****/
        GirlsViewModel girlsViewModel = viewModelProvider.get(GirlsViewModel.class);

先看第一步獲得的源代碼:

    public static ViewModelProvider of(@NonNull FragmentActivity activity) {

        /**********獲得AndroidViewModelFactory ( 內(nèi)部是單例的 )*******/
        ViewModelProvider.AndroidViewModelFactory factory =
                ViewModelProvider.AndroidViewModelFactory.getInstance(
                        checkApplication(activity));

        /*****創(chuàng)建一個ViewModelProvider( 傳入的兩個參數(shù)是重點 )*****/
        return new ViewModelProvider(ViewModelStores.of(activity), factory);

    }

上面的兩步其實很關(guān)鍵了免都,獲得AndroidViewModelFactory 锉罐,AndroidViewModelFactory其實是ViewModelProvider的靜態(tài)內(nèi)部類,看調(diào)用方式就知道是一個單例的绕娘,就是我們的應用只有有一個單例的 AndroidViewModelFactory存在脓规,看源碼:

  /*****`AndroidViewModelFactory `其實是`ViewModelProvider`的靜態(tài)內(nèi)部類******/
 public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

        private static AndroidViewModelFactory sInstance;

        /********獲得AndroidViewModelFactory 單例**********/
        public static AndroidViewModelFactory getInstance(@NonNull Application application) {
            if (sInstance == null) {
                sInstance = new AndroidViewModelFactory(application);
            }
            return sInstance;
        }

        private Application mApplication;
        
        /*************其實構(gòu)造方式是public 的,還是可以new的****************/
        public AndroidViewModelFactory(@NonNull Application application) {
            mApplication = application;
        }
        
        /******其實這里就是創(chuàng)建ViewModel的關(guān)鍵地方险领,根據(jù)給出的Class反射創(chuàng)建需要的ViewModel*******/
        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                //noinspection TryWithIdenticalCatches
                try {
                    return modelClass.getConstructor(Application.class).newInstance(mApplication);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                } catch (InstantiationException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                }
            }
            return super.create(modelClass);
        }
    }

重點我都標注在注釋里了侨舆,請耐心看一遍【钅埃看到這里我知道了一個全局的AndroidViewModelFactory工具類挨下,作用就是反射創(chuàng)建我們想要的類ViewModel,其實功能簡單的脐湾!

獲得到的單例AndroidViewModelFactory是創(chuàng)建ViewModelProvider的第二個參數(shù)臭笆,下面我們看第一個參數(shù)。

第一個參數(shù)是這樣: ViewModelStores.of(activity)
看源碼:

3.ViewModelStores靜態(tài)方法為Activity創(chuàng)建一個ViewModelStore

解釋我就放在注釋了秤掌,大家看下面的注釋把:

    @MainThread
    public static ViewModelStore of(@NonNull FragmentActivity activity) {
        //如果你的Activity實現(xiàn)了ViewModelStoreOwner接口具備了提供
        //ViewModelStore 的功能就直接獲取返回愁铺,通常我們的Activity都不會去實現(xiàn)這個功能
        if (activity instanceof ViewModelStoreOwner) {
            return ((ViewModelStoreOwner) activity).getViewModelStore();
        }
        //系統(tǒng)為你的Activity添加一個具有提供ViewModelStore 的holderFragment
        return holderFragmentFor(activity).getViewModelStore();
    }

其實解析ViewModelStore就可以解釋ViewModel的存儲,解析 holderFragmentFor(activity).getViewModelStore() 就可解釋ViewModel為什么可以在Activity配置發(fā)生變化的情況下人不銷毀闻鉴,這些我們就在下面去解釋茵乱。我第一步重點解釋創(chuàng)建不關(guān)心其他的。

到這里我們要知道:
第一: AndroidViewModelFactory在正常情況下是全局單例只有一個,只是一個反射創(chuàng)建對象的工具類。
第二:ViewModelProvider是每次獲取創(chuàng)建ViewModel的時候都會創(chuàng)建一個新的湘换。
第三:ViewModelStore是每一個Activity或者Fragment都有一個仰担。

關(guān)注ViewModel創(chuàng)建:

//viewModelProvider的get方法
 viewModelProvider.get(GirlsViewModel.class);
4.viewModelProvider的get方法

會用 DEFAULT_KEY 和 類名組成一個key值去獲取,接著向下看:


5.ViewModel的創(chuàng)建關(guān)鍵方法

代碼很簡單玷氏,流程如下:
(1) 先從mViewModelStore中使用key去獲取ViewModel, mViewModelStore中是使用HashMap去存儲一個Activity或者FragmentViewModel的堵未。如果獲取到就返回。
(2) 沒獲取到就使用單例mFactory的create方法反射創(chuàng)建ViewModel,create方法的代碼在上面貼出來了盏触。
(3) 使用Key存入mViewModelStore 并返回渗蟹。

到這里ViewModel的創(chuàng)建基本就是講完了,但是可能還是有些懵逼赞辩。下面接著看吧雌芽。

一句話總結(jié)ViewModel是怎么被創(chuàng)建的:

創(chuàng)建一個ViewModelProvider,使用ViewModelProvider內(nèi)部的全局單例AndroidViewModelFactory來反射創(chuàng)建 ViewModel,并把創(chuàng)建的ViewModel存入傳入的ViewModelStore中辨嗽!

二世落、ViewModel是怎么存儲的?

存儲就是要講解ViewModelStore了糟需。
直接看源代碼:

6.ViewModelStore源碼

代碼就這數(shù)的清的幾行屉佳,就是一個 HashMap用存儲ViewModel谷朝。提供get,put,clear三個方法。
上面說了ViewModelStore是每一個Activity或者ViewModel都有一個的武花,當Activity或者Fragment銷毀的時候就會調(diào)用clear方法了圆凰。

ViewModelStore被誰創(chuàng)建,被誰持有体箕?-------------------> +_+
搶答:被HolderFragment創(chuàng)建和持有专钉!

HolderFragment跟我們的Activity或者Fragment有什么關(guān)系?-------------------> +_+
搶答:當我們要給Activity或者Fragment創(chuàng)建ViewModel的時候累铅,系統(tǒng)就會為Activity或者Fragment添加一個HolderFragment跃须,HolderFragment中會創(chuàng)建持有一個ViewModelStore

HolderFragment怎么創(chuàng)建怎么被添加争群?-------------------> +_+

7.每次獲取ViewModel都會創(chuàng)建一個ViewModelProvider

這一步其實可以分解為下面的的樣子:

        /**為Activity或者Fragment創(chuàng)建ViewModelStore*/
        ViewModelStore viewModelStore = ViewModelStores.of(activity);

        /**為本次的ViewModel獲取創(chuàng)建一個ViewModelProvider*/
        ViewModelProvider viewModelProvider =  new ViewModelProvider(viewModelStore, factory);

完成了上面兩步才可以這樣: viewModelProvider.get(想要的ViewModel.class);

正是

       /**為Activity或者Fragment創(chuàng)建ViewModelStore*/
       ViewModelStore viewModelStore = ViewModelStores.of(activity / fragment);

這步為我們的 activity / fragment 注入了一個HolderFragment回怜,創(chuàng)建HolderFragment的時候會創(chuàng)建的時候會創(chuàng)建一個ViewModelStore實例,到這里也解釋了一下 ViewModelStore被誰創(chuàng)建换薄,被誰持有玉雾?的問題。

上面我有提過ViewModelStoreOwner這個接口轻要,其實我們這里說的HolderFragment就是實現(xiàn)了這個接口的Fragment复旬。

一句話總結(jié)ViewModel是怎么被存儲的:

這是上面一句話總結(jié)ViewModel的創(chuàng)建:

8.ViewModel創(chuàng)建一句話總結(jié)

這句創(chuàng)建總結(jié)其實也說明了ViewModel的存儲。
進一步解釋:
ViewModel是存儲在當前Activity / FragmentHolderFragment 中的ViewModelStore的HashMap中冲泥,我們可以get,put或者在Activity / Fragment銷毀的時候HolderFragment會跟隨銷毀驹碍,在HolderFragmentonDestroy方法中調(diào)用mViewModelStoreclear方法。
9.HolderFragment伴隨銷毀時調(diào)用自己所有ViewModel的onCleared方法

三凡恍、ViewModel為什么可以實現(xiàn)旋轉(zhuǎn)屏幕不銷毀志秃?

ViewModel的創(chuàng)建獲取方式是: 為Activity / Fragment創(chuàng)建一個ViewModelStore,獲取到AndroidViewModelFactory單例嚼酝,用這個兩個數(shù)據(jù)創(chuàng)建一個ViewModelProvider,在創(chuàng)建的ViewModelProvider中可以get我們要的ViewModel浮还。

Activity / Fragment創(chuàng)建一個ViewModelStore,就是調(diào)用下面的方法:

10.HolderFragment被注入到Activity / Fragment

holderFragmentFor(activity)源碼:
11.holderFragmentFor(activity)

12.單例的HolderFragmentManager

holderFragmentFor(activity)方法每一步都有解釋闽巩,很詳細:


        HolderFragment holderFragmentFor(FragmentActivity activity) {

            //獲取Activity的FragmentManager
            FragmentManager fm = activity.getSupportFragmentManager();

            //通過HOLDER_TAG在FragmentManager中需要HolderFragment
            HolderFragment holder = findHolderFragment(fm);

            //獲得的HolderFragment不為空就返回
            if (holder != null) {
                return holder;
            }

            //在Map<Activity, HolderFragment>緩存中獲取HolderFragment
            //Activity為key钧舌,所以每一個Activity或者Fragment只會有一個HolderFragment
            holder = mNotCommittedActivityHolders.get(activity);

            //不為空就返回
            if (holder != null) {
                return holder;
            }


            //在Application中注冊一個所有Activity生命周期回調(diào)監(jiān)聽,這里只會注冊一次
            //這里注冊Activity生命周期監(jiān)聽的目的是在Activity銷毀的時候好移除Map<Activity, HolderFragment>中的對應數(shù)據(jù)
            if (!mActivityCallbacksIsAdded) {
                mActivityCallbacksIsAdded = true;
                activity.getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks);
            }

            //new HolderFragment()并通過fm添加到Activity并返回
            holder = createHolderFragment(fm);

            //添加到Map<Activity, HolderFragment>緩存
            mNotCommittedActivityHolders.put(activity, holder);

            //返回
            return holder;
        }

createHolderFragment()方法重點關(guān)注一下:

12.createHolderFragment

就是創(chuàng)建了一個HolderFragment涎跨,使用傳入的FragmentManager添加進去洼冻!

這是上面調(diào)用的構(gòu)造方法:


13.HolderFragment

被設(shè)置setRetainInstance(true)后的Fragment添加到Activity中去了,會怎么樣隅很?

setRetainInstance(boolean) 是Fragment中的一個方法撞牢。將這個方法設(shè)置為true就可以使當前Fragment在Activity重建時存活下來, 如果不設(shè)置或者設(shè)置為 false, 當前 Fragment 會在 Activity 重建時同樣發(fā)生重建, 以至于被新建的對象所替代。
在setRetainInstance(boolean)為true的 Fragment (就是HolderFragment)中放一個專門用于存儲ViewModel的Map, 這樣Map中所有的ViewModel都會幸免于Activity的配置改變導致的重建,讓需要創(chuàng)建ViewModel的Activity, Fragment都綁定一個這樣的Fragment(就是HolderFragment), 將ViewModel存放到這個 Fragment 的 Map 中, ViewModel 組件就這樣實現(xiàn)了普泡。

實現(xiàn)原理就是巧妙滴借用了Fragment的setRetainInstance(true)屬性播掷。關(guān)于setRetainInstance更多介紹可以參考:Android應用開發(fā):Fragment的非中斷保存setRetaineInstance

我這里可以展示一下setRetainInstance(true)屬性對生命周期的影響,在一個Activity中加入一個具有setRetainInstance(true)屬性的Fragment:


setRetainInstance(true)屬性演示

三秒鐘后展示出了我們的Fragment撼班,生命周期如下:


展示生命周期

然后我們點擊模擬器的旋轉(zhuǎn)屏幕按鈕:


旋轉(zhuǎn)屏幕按鈕

生命周期變化:
旋轉(zhuǎn)生命周期

可以看到Activity因為配置改變了歧匈,調(diào)了onDestroy方法,但是我們的setRetainInstance(true)屬性的Fragment沒有調(diào)用onDestroy方法砰嘁,說明Fragment得以幸存下來了件炉。

退出當前Activity但是不退出應用后的生命周期:

退出Activity后生命周期

這時候Activity和Fragment的onDestroy生命周期方法先后被調(diào)用了。

在我的HolderFragmentonDestroy方法中矮湘,會調(diào)用mViewModelStore中所有ViewModelonCleared方法斟冕。

四、總結(jié):

關(guān)于ViewModel的實現(xiàn)結(jié)構(gòu)圖可以參考如下:圖片來源https://blog.csdn.net/zhuzp_blog/article/details/78910535

13.ViewModel的實現(xiàn)結(jié)構(gòu)圖

1.ViewModel 以鍵值對的形式存在Activity或者Fragment的HolderFragment
ViewModelStore的HashMap中缅阳。

2.一個Activity或者Fragment可以有很多個ViewModel磕蛇。

3.一個Activity或者Fragment只會有一個HolderFragment

4.Activity或者Fragment的HolderFragment會保存在全局單例的HolderFragmentManager的HashMap中十办,在Activity或者Fragment銷毀的時候會移除HashMap中對應的value秀撇。

5.因為ViewModel是以Activity或者Fragment為存在基礎(chǔ),所以ViewModel可以在當前Activity和Fragment中實現(xiàn)數(shù)據(jù)共享向族,前提是傳入相同的key值呵燕。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市件相,隨后出現(xiàn)的幾起案子再扭,更是在濱河造成了極大的恐慌,老刑警劉巖夜矗,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泛范,死亡現(xiàn)場離奇詭異,居然都是意外死亡紊撕,警方通過查閱死者的電腦和手機敦跌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逛揩,“玉大人,你說我怎么就攤上這事麸俘”缁” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵从媚,是天一觀的道長逞泄。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么喷众? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任各谚,我火速辦了婚禮,結(jié)果婚禮上到千,老公的妹妹穿的比我還像新娘昌渤。我一直安慰自己,他們只是感情好憔四,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布膀息。 她就那樣靜靜地躺著,像睡著了一般了赵。 火紅的嫁衣襯著肌膚如雪潜支。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天柿汛,我揣著相機與錄音冗酿,去河邊找鬼。 笑死络断,一個胖子當著我的面吹牛裁替,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妓羊,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胯究,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了躁绸?” 一聲冷哼從身側(cè)響起裕循,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎净刮,沒想到半個月后剥哑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡淹父,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年株婴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片暑认。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡困介,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蘸际,到底是詐尸還是另有隱情座哩,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布粮彤,位于F島的核電站根穷,受9級特大地震影響姜骡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜屿良,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一圈澈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尘惧,春花似錦康栈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至重慢,卻和暖如春饥臂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背似踱。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工隅熙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人核芽。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓囚戚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轧简。 傳聞我的和親對象是個殘疾皇子驰坊,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

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