Android架構(gòu)組件:使用帶有會(huì)議室的分頁(yè)庫(kù)

在本教程中邀泉,我將向您展示如何在Android應(yīng)用程序中使用Android架構(gòu)組件中的Paging庫(kù)和Room支持的數(shù)據(jù)庫(kù)。

您將學(xué)習(xí)如何使用Paging庫(kù)從Room支持的數(shù)據(jù)庫(kù)高效加載大型數(shù)據(jù)集 - 在RecyclerView中滾動(dòng)時(shí)為您的用戶提供更流暢的體驗(yàn)迫靖。

什么是分頁(yè)庫(kù)?

Paging庫(kù)是添加到Architecture Components的另一個(gè)庫(kù)悔常。該庫(kù)有助于有效地管理大型數(shù)據(jù)集的加載和顯示RecyclerView循帐。根據(jù)官方文件:

分頁(yè)庫(kù)使您可以更輕松地在應(yīng)用程序中逐漸和優(yōu)雅地加載數(shù)據(jù)RecyclerView

如果Android應(yīng)用程序的任何部分要從本地或遠(yuǎn)程數(shù)據(jù)源顯示大型數(shù)據(jù)集,但一次只顯示部分?jǐn)?shù)據(jù)集砾跃,則應(yīng)考慮使用分頁(yè)庫(kù)骏啰。這有助于提高應(yīng)用的性能!

那么為什么要使用尋呼庫(kù)抽高?

既然您已經(jīng)看過(guò)Paging庫(kù)的介紹判耕,您可能會(huì)問(wèn),為什么要使用它翘骂?以下是您應(yīng)該考慮在加載大型數(shù)據(jù)集時(shí)使用它的一些原因RecyclerView壁熄。

  • 它不會(huì)請(qǐng)求不需要的數(shù)據(jù)。當(dāng)用戶滾動(dòng)列表時(shí)碳竟,此庫(kù)僅請(qǐng)求用戶可見(jiàn)的數(shù)據(jù)草丧。
  • 節(jié)省用戶的電池并消耗更少的帶寬。因?yàn)樗徽?qǐng)求所需的數(shù)據(jù)莹桅,所以這節(jié)省了一些設(shè)備資源昌执。

在處理大量數(shù)據(jù)時(shí)效率不高,因?yàn)榈讓訑?shù)據(jù)源會(huì)檢索所有數(shù)據(jù)诈泼,即使只有一部分?jǐn)?shù)據(jù)要顯示給用戶懂拾。在這種情況下,我們應(yīng)該考慮分頁(yè)數(shù)據(jù)铐达。

1. 創(chuàng)建Android Studio項(xiàng)目

啟動(dòng)Android Studio 3并創(chuàng)建一個(gè)名為空活動(dòng)的新項(xiàng)目 MainActivity岖赋。一定要檢查包含Kotlin支持

Android Studio創(chuàng)建項(xiàng)目屏幕

2. 添加架構(gòu)組件

創(chuàng)建新項(xiàng)目后瓮孙,在build.gradle中添加以下依賴項(xiàng)唐断。在本教程中,我們使用的是最新的Paging庫(kù)版本1.0.1杭抠,而Room是1.1.1(截至撰寫(xiě)本文時(shí))栗涂。

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "android.arch.persistence.room:runtime:1.1.1"
    kapt "android.arch.persistence.room:compiler:1.1.1"
    implementation "android.arch.paging:runtime:1.0.1"
    implementation "com.android.support:recyclerview-v7:27.1.1"
}

這些工件可在Google的Maven存儲(chǔ)庫(kù)中找到。

allprojects {
    repositories {
        google()
        jcenter()
    }
}

通過(guò)添加依賴項(xiàng)祈争,我們已經(jīng)教過(guò)Gradle如何查找?guī)旖锍獭4_保在添加項(xiàng)目后記得同步項(xiàng)目。

3. 創(chuàng)建實(shí)體

創(chuàng)建一個(gè)新的Kotlin數(shù)據(jù)類Person菩混。為簡(jiǎn)單起見(jiàn)忿墅,我們的Person實(shí)體只有兩個(gè)字段:

一個(gè)唯一的ID(id)
人的名字(name)
另外,包括一個(gè)toString( 簡(jiǎn)單返回的方法name沮峡。

import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey
 
@Entity(tableName = "persons")
data class Person(
        @PrimaryKey val id: String,
        val name: String
) {
    override fun toString() = name
}

4. 創(chuàng)建DAO

如您所知疚脐,我們需要使用Room庫(kù)來(lái)訪問(wèn)應(yīng)用程序的數(shù)據(jù),我們需要數(shù)據(jù)訪問(wèn)對(duì)象(DAO)邢疙。在我們自己的案例中棍弄,我們創(chuàng)建了一個(gè) PersonDao望薄。

import android.arch.lifecycle.LiveData
import android.arch.paging.DataSource
import android.arch.persistence.room.Dao
import android.arch.persistence.room.Delete
import android.arch.persistence.room.Insert
import android.arch.persistence.room.Query
 
@Dao
interface PersonDao {
 
    @Query("SELECT * FROM persons")
    fun getAll(): LiveData<List<Person>>
 
    @Query("SELECT * FROM persons")
    fun getAllPaged(): DataSource.Factory<Int, Person>
 
    @Insert
    fun insertAll(persons: List<Person>)
 
    @Delete
    fun delete(person: Person)
}

在我們PersonDao班上,我們有兩種@Query方法呼畸。其中之一是 getAll()痕支,它返回一個(gè)LiveData包含Person對(duì)象列表的東西。另一個(gè)是 getAllPaged()蛮原,返回一個(gè)DataSource.Factory卧须。

根據(jù)官方文件,該DataSource課程是:

用于將快照數(shù)據(jù)頁(yè)面加載到的基類PagedList儒陨。
A PagedList是一種List在Android中顯示分頁(yè)數(shù)據(jù)的特殊類型:

A PagedList是一個(gè)List花嘶,它從a中以塊(頁(yè))加載其數(shù)據(jù)DataSource”哪可以使用椭员,訪問(wèn)項(xiàng)目get(int),并可以觸發(fā)進(jìn)一步加載loadAround(int)笛园。
我們Factory在DataSource類中調(diào)用靜態(tài)方法隘击,該方法用作工廠(創(chuàng)建對(duì)象而不必指定將要?jiǎng)?chuàng)建的對(duì)象的確切類)DataSource。此靜態(tài)方法有兩種數(shù)據(jù)類型:

標(biāo)識(shí)項(xiàng)目的關(guān)鍵DataSource喘沿。請(qǐng)注意闸度,對(duì)于Room查詢竭贩,頁(yè)面是編號(hào)的 - 因此我們將其Integer用作頁(yè)面標(biāo)識(shí)符類型蚜印。使用Paging庫(kù)可以使用“鍵控”頁(yè)面,但Room目前不提供留量。
DataSources 加載的列表中的項(xiàng)目或?qū)嶓w(POJO)的類型窄赋。

5. 創(chuàng)建數(shù)據(jù)庫(kù)

這是我們的Room數(shù)據(jù)庫(kù)類的AppDatabase樣子:

import android.arch.persistence.db.SupportSQLiteDatabase
import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.content.Context
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.chikeandroid.pagingtutsplus.utils.DATABASE_NAME
import com.chikeandroid.pagingtutsplus.workers.SeedDatabaseWorker
 
@Database(entities = [Person::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun personDao(): PersonDao
 
    companion object {
 
        // For Singleton instantiation
        @Volatile private var instance: AppDatabase? = null
 
        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance
                        ?: buildDatabase(context).also { instance = it }
            }
        }
 
        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
                    .addCallback(object : RoomDatabase.Callback() {
                        override fun onCreate(db: SupportSQLiteDatabase) {
                            super.onCreate(db)
                            val request = OneTimeWorkRequestBuilder<SeedDatabaseWorker>().build()
                            WorkManager.getInstance()?.enqueue(request)
                        }
                    })
                    .build()
        }
    }
}

在這里,我們創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù)實(shí)例楼熄,并使用新的WorkManager API預(yù)先填充了數(shù)據(jù)忆绰。請(qǐng)注意,預(yù)先填充的數(shù)據(jù)只是1,000個(gè)名稱的列表(深入了解提供的示例源代碼以了解更多信息)可岂。

6. 創(chuàng)建ViewModel

為了讓我們以生命周期意識(shí)的方式存儲(chǔ)错敢,觀察和提供數(shù)據(jù),我們需要一個(gè)ViewModel缕粹。我們的PersonsViewModel稚茅,它擴(kuò)展了AndroidViewModel類,是要作為我們的ViewModel平斩。

import android.app.Application
import android.arch.lifecycle.AndroidViewModel
import android.arch.lifecycle.LiveData
import android.arch.paging.DataSource
import android.arch.paging.LivePagedListBuilder
import android.arch.paging.PagedList
import com.chikeandroid.pagingtutsplus.data.AppDatabase
import com.chikeandroid.pagingtutsplus.data.Person
 
class PersonsViewModel constructor(application: Application)
    : AndroidViewModel(application) {
 
    private var personsLiveData: LiveData<PagedList<Person>>
 
    init {
        val factory: DataSource.Factory<Int, Person> =
        AppDatabase.getInstance(getApplication()).personDao().getAllPaged()
 
        val pagedListBuilder: LivePagedListBuilder<Int, Person>  = LivePagedListBuilder<Int, Person>(factory,
                50)
        personsLiveData = pagedListBuilder.build()
    }
 
    fun getPersonsLiveData() = personsLiveData
}

在這個(gè)類中亚享,我們有一個(gè)名為的字段personsLiveData。這個(gè)字段是一個(gè)簡(jiǎn)單的LiveData持有一個(gè)PagedList的 Person對(duì)象绘面。因?yàn)檫@是一個(gè)LiveData欺税,我們的UI(Activity或Fragment)將通過(guò)調(diào)用getter方法來(lái)觀察這些數(shù)據(jù)getPersonsLiveData()侈沪。

我們personsLiveData在init塊內(nèi)初始化。在這個(gè)塊中晚凿,我們DataSource.Factory通過(guò)調(diào)用 對(duì)象的 AppDatabase單例來(lái)獲得 PersonDao亭罪。當(dāng)我們得到這個(gè)對(duì)象時(shí),我們打電話getAllPaged()晃虫。

然后我們創(chuàng)建一個(gè)LivePagedListBuilder皆撩。以下是官方文檔中關(guān)于a的說(shuō)明LivePagedListBuilder:

生成器LiveData<PagedList>,給定a DataSource.Factory和a PagedList.Config哲银。
我們提供構(gòu)造函數(shù)a DataSource.Factory作為第一個(gè)參數(shù)扛吞,頁(yè)面大小作為第二個(gè)參數(shù)(在我們自己的情況下,頁(yè)面大小將為50)荆责。通常滥比,您應(yīng)該選擇一個(gè)大于您可能一次向用戶顯示的最大數(shù)量的大小。最后做院,我們打電話build()給我們構(gòu)建并返回給我們LiveData<PagedList>盲泛。

7. 創(chuàng)建PagedListAdapter

要PagedList在a中顯示我們的數(shù)據(jù)RecyclerView,我們需要一個(gè)PagedListAdapter键耕。以下是官方文檔中對(duì)此類的明確定義:

RecyclerView.Adapter用于從PagedLista中的s 呈現(xiàn)分頁(yè)數(shù)據(jù)的基類RecyclerView寺滚。
所以我們創(chuàng)建了一個(gè)PersonAdapter擴(kuò)展 PagedListAdapter。

import android.arch.paging.PagedListAdapter
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.chikeandroid.pagingtutsplus.R
import com.chikeandroid.pagingtutsplus.data.Person
import kotlinx.android.synthetic.main.item_person.view.*
 
class PersonAdapter(val context: Context) : PagedListAdapter<Person, PersonAdapter.PersonViewHolder>(PersonDiffCallback()) {
 
    override fun onBindViewHolder(holderPerson: PersonViewHolder, position: Int) {
        var person = getItem(position)
 
        if (person == null) {
            holderPerson.clear()
        } else {
            holderPerson.bind(person)
        }
    }
 
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PersonViewHolder {
        return PersonViewHolder(LayoutInflater.from(context).inflate(R.layout.item_person,
                parent, false))
    }
 
 
    class PersonViewHolder (view: View) : RecyclerView.ViewHolder(view) {
 
        var tvName: TextView = view.name
 
        fun bind(person: Person) {
            tvName.text = person.name
        }
 
        fun clear() {
            tvName.text = null
        }
 
    }
}

PagedListAdapter就像使用的任何其他子類一樣使用RecyclerView.Adapter屈雄。換句話說(shuō)村视,你必須實(shí)現(xiàn)方法 onCreateViewHolder()和onBindViewHolder()。

要擴(kuò)展PagedListAdapter抽象類酒奶,您必須提供其構(gòu)造函數(shù) - PageLists(這應(yīng)該是一個(gè)普通的舊Java類:POJO)的類型蚁孔,以及擴(kuò)展ViewHolder適配器將使用的類的類。在我們的例子中惋嚎,我們給它Person杠氢,并PersonViewHolder分別作為第一和第二個(gè)參數(shù)。

請(qǐng)注意另伍,PagedListAdapter需要將其傳遞 DiffUtil.ItemCallback給PageListAdapter構(gòu)造函數(shù)鼻百。DiffUtil是一個(gè)RecyclerView實(shí)用程序類,可以計(jì)算兩個(gè)列表之間的差異摆尝,并輸出將第一個(gè)列表轉(zhuǎn)換為第二個(gè)列表的更新操作列表温艇。ItemCallback是一個(gè)內(nèi)部抽象靜態(tài)類(內(nèi)部DiffUtil),用于計(jì)算列表中兩個(gè)非空項(xiàng)之間的差異结榄。

具體來(lái)說(shuō)中贝,我們提供PersonDiffCallback給我們的 PagedListAdapter構(gòu)造函數(shù)。

import android.support.v7.util.DiffUtil
import com.chikeandroid.pagingtutsplus.data.Person
 
class PersonDiffCallback : DiffUtil.ItemCallback<Person>() {
 
    override fun areItemsTheSame(oldItem: Person, newItem: Person): Boolean {
        return oldItem.id == newItem.id
    }
 
    override fun areContentsTheSame(oldItem: Person?, newItem: Person?): Boolean {
        return oldItem == newItem
    }
}

因?yàn)槲覀冋趯?shí)現(xiàn)DiffUtil.ItemCallback臼朗,所以我們必須實(shí)現(xiàn)兩種方法:areItemsTheSame()和areContentsTheSame()邻寿。

areItemsTheSame 調(diào)用以檢查兩個(gè)對(duì)象是否代表同一個(gè)項(xiàng)目蝎土。例如,如果您的項(xiàng)目具有唯一ID绣否,則此方法應(yīng)檢查其ID相等誊涯。true如果兩個(gè)項(xiàng)表示相同的對(duì)象或false它們不同,則此方法返回蒜撮。
areContentsTheSame 調(diào)用以檢查兩個(gè)項(xiàng)目是否具有相同的數(shù)據(jù)暴构。true如果項(xiàng)目的內(nèi)容相同或者false它們不同,則此方法返回段磨。
我們的PersonViewHolder內(nèi)心階層只是一個(gè)典型的 RecyclerView.ViewHolder取逾。它負(fù)責(zé)根據(jù)需要將數(shù)據(jù)從我們的模型綁定到列表中的行的小部件中。

class PersonAdapter(val context: Context) : PagedListAdapter<Person, PersonAdapter.PersonViewHolder>(PersonDiffCallback()) {
     
    // ... 
     
    class PersonViewHolder (view: View) : RecyclerView.ViewHolder(view) {
 
        var tvName: TextView = view.name
 
        fun bind(person: Person) {
            tvName.text = person.name
        }
 
        fun clear() {
            tvName.text = null
        }
 
    }
}

8. 顯示結(jié)果

在我們onCreate()的MainActivity苹支,我們只是做了以下:

viewModel 使用實(shí)用程序類初始化我們的 字段ViewModelProviders
創(chuàng)建一個(gè)實(shí)例 PersonAdapter
配置我們的 RecyclerView
綁定 PersonAdapter到RecyclerView
觀察LiveData并 通過(guò)調(diào)用將PagedList對(duì)象提交給PersonAdaptersubmitList()

import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.RecyclerView
import com.chikeandroid.pagingtutsplus.adapter.PersonAdapter
import com.chikeandroid.pagingtutsplus.viewmodels.PersonsViewModel
 
class MainActivity : AppCompatActivity() {
 
    private lateinit var viewModel: PersonsViewModel
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 
        viewModel = ViewModelProviders.of(this).get(PersonsViewModel::class.java)
 
        val adapter = PersonAdapter(this)
        findViewById<RecyclerView>(R.id.name_list).adapter = adapter
 
        subscribeUi(adapter)
    }
 
    private fun subscribeUi(adapter: PersonAdapter) {
        viewModel.getPersonLiveData().observe(this, Observer { names ->
            if (names != null) adapter.submitList(names)
        })
    }
}

最后砾隅,當(dāng)您運(yùn)行應(yīng)用程序時(shí),結(jié)果如下:

教程結(jié)果截圖

滾動(dòng)時(shí)债蜜,Room可以通過(guò)一次加載50個(gè)項(xiàng)目并將它們提供給我們PersonAdapter的子類來(lái)防止間隙PagingListAdapter晴埂。但請(qǐng)注意,并非所有數(shù)據(jù)源都會(huì)快速加載寻定。加載速度還取決于Android設(shè)備的處理能力儒洛。

9.與RxJava集成

如果您正在使用或想要在項(xiàng)目中使用RxJava,則分頁(yè)庫(kù)包含另一個(gè)有用的工件: RxPagedListBuilder狼速。您使用此工件而不是 LivePagedListBuilderRxJava支持琅锻。

您只需創(chuàng)建一個(gè)實(shí)例 RxPagedListBuilder,提供與LivePagedListBuilder-the DataSource.Factory和頁(yè)面大小相同的參數(shù) 唐含。然后調(diào)用 buildObservable()buildFlowable()返回一個(gè)ObservableFlowable 您的PagedList分別浅浮。

要顯式提供 Scheduler數(shù)據(jù)加載工作沫浆,請(qǐng)調(diào)用setter方法 setFetchScheduler()捷枯。為了提供Scheduler結(jié)果(例如 AndroidSchedulers.mainThread()),只需撥打電話即可 setNotifyScheduler()专执。默認(rèn)情況下淮捆,setNotifyScheduler()默認(rèn)為UI線程,setFetchScheduler()默認(rèn)為I / O線程池本股。

結(jié)論

在本教程中攀痊,您學(xué)習(xí)了如何使用Room 的Android架構(gòu)組件(Android Jetpack的一部分)輕松使用Paging組件 。這有助于我們有效地從本地?cái)?shù)據(jù)庫(kù)加載大型數(shù)據(jù)集拄显,以便在滾動(dòng)瀏覽列表時(shí)實(shí)現(xiàn)更流暢的用戶體驗(yàn)RecyclerView苟径。

想學(xué)習(xí)更多Android知識(shí),或者獲取相關(guān)資料請(qǐng)加入Android技術(shù)開(kāi)發(fā)交流2群:935654177躬审。本群可免費(fèi)獲取Gradle棘街,RxJava蟆盐,小程序,Hybrid遭殉,移動(dòng)架構(gòu)石挂,NDK,React Native险污,性能優(yōu)化等技術(shù)教程痹愚!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蛔糯,隨后出現(xiàn)的幾起案子拯腮,更是在濱河造成了極大的恐慌,老刑警劉巖蚁飒,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疾瓮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡飒箭,警方通過(guò)查閱死者的電腦和手機(jī)狼电,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)弦蹂,“玉大人肩碟,你說(shuō)我怎么就攤上這事⊥勾唬” “怎么了削祈?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)脑漫。 經(jīng)常有香客問(wèn)我髓抑,道長(zhǎng),這世上最難降的妖魔是什么优幸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任吨拍,我火速辦了婚禮,結(jié)果婚禮上网杆,老公的妹妹穿的比我還像新娘羹饰。我一直安慰自己,他們只是感情好碳却,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布队秩。 她就那樣靜靜地躺著,像睡著了一般昼浦。 火紅的嫁衣襯著肌膚如雪馍资。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天关噪,我揣著相機(jī)與錄音鸟蟹,去河邊找鬼物舒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛戏锹,可吹牛的內(nèi)容都是我干的冠胯。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锦针,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荠察!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起奈搜,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悉盆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后馋吗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體焕盟,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年宏粤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脚翘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绍哎,死狀恐怖来农,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崇堰,我是刑警寧澤沃于,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站海诲,受9級(jí)特大地震影響繁莹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜特幔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一咨演、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敬辣,春花似錦雪标、人聲如沸零院。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)告抄。三九已至撰茎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間打洼,已是汗流浹背龄糊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工逆粹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人炫惩。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓僻弹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親他嚷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蹋绽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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