Android應(yīng)用界面開(kāi)發(fā)——BroadcastReceiver(實(shí)現(xiàn)基于Service的音樂(lè)播放器)

BroadcastReceiver:廣播接收者都伪,Android四大組件之一,這個(gè)組件本質(zhì)上就是一個(gè)全局監(jiān)聽(tīng)器,用于監(jiān)聽(tīng)系統(tǒng)全局的廣播消息。由于BroadcastReceiver是一個(gè)全局監(jiān)聽(tīng)器虑椎,因此它可以方便的實(shí)現(xiàn)系統(tǒng)中不同組件之間的通信。

BroadcastReceiver簡(jiǎn)介


BroadcastReceiver用于接收程序(開(kāi)發(fā)者開(kāi)發(fā)的程序和系統(tǒng)程序)發(fā)出的Broadcast Intent俱笛,程序啟動(dòng)BroadcastReceiver需要兩步:

  • 創(chuàng)建需要啟動(dòng)的BroadcastReceiver的Intent捆姜。
  • 調(diào)用Context的sendBroadcast()或sendOrderedBroadcast()方法來(lái)啟動(dòng)指定的BroadcastReceiver。

實(shí)現(xiàn)BroadcastReceiver只要重寫B(tài)roadcastReceiver的onReceive(Context context, Intent intent)方法即可迎膜。

實(shí)現(xiàn)了BroadcastReceiver泥技,接著應(yīng)該指定該BroadcastReceiver能匹配的Intent,有兩種方式:

  • 靜態(tài)注冊(cè):

    • 在AndroidManifest.xml中配置:
    <receiver android:name=".MyReceiver">
              <intent-filter>
                  <action android:name="com.trampcr.musicplayer.PLAY_ACTION"/>
              </intent-filter>
    </receiver>
    
  • 動(dòng)態(tài)注冊(cè):

    • 使用代碼進(jìn)行指定磕仅,調(diào)用BroadcastReceiver的Context的registerReceiver(BroadcastReceiver receiver, IntentFilter filter)方法指定:
    IntentFilter intentFilter = new IntentFilter("com.trampcr.musicplayer.PLAY_ACTION");
    MyReceiver receiver = new MyReceiver();
    registerReceiver(receiver, intentFilter);
    

每次系統(tǒng)廣播事件發(fā)生后珊豹,系統(tǒng)會(huì)創(chuàng)建對(duì)應(yīng)的BroadcastReceiver實(shí)例,并自動(dòng)觸發(fā)它的onReceiver()方法榕订,如果onReceiver()方法不能在10秒內(nèi)完成店茶,Android就會(huì)認(rèn)為該程序無(wú)響應(yīng)(所以onReceiver()方法中不能進(jìn)行耗時(shí)操作)。onReceiver()方法執(zhí)行完后劫恒,BroadcastReceiver實(shí)例就會(huì)被銷毀贩幻。

如果需要根據(jù)Broadcast完成比較耗時(shí)的操作,則應(yīng)該考慮通過(guò)Intent啟動(dòng)一個(gè)Service來(lái)完成两嘴,不考慮使用新線程完成耗時(shí)操作的原因:
BroadcastReceiver本身的生命周期很短丛楚,很可能子線程還沒(méi)有結(jié)束,BroadcastReceiver就已經(jīng)退出了憔辫。

發(fā)送廣播


調(diào)用Context的sendBroadcast(Intent intent)方法發(fā)送廣播趣些,這條廣播將會(huì)啟動(dòng)intent參數(shù)所對(duì)應(yīng)的BroadcastReceiver。

該程序的Activity界面包含一個(gè)按鈕螺垢,用于向外發(fā)送廣播喧务。代碼如下:

public class MainActivity extends AppCompatActivity {
    
    private Button mSendBroadcast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mSendBroadcast = (Button) findViewById(R.id.send_broadcast);
        
        mSendBroadcast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                //設(shè)置Intent的Action屬性
                intent.setAction("com.trampcr.musicplayer.PLAY_ACTION");
                intent.putExtra("msg", "simple message");
                //發(fā)送廣播
                sendBroadcast(intent);
            }
        });
    }
}

上述程序用于創(chuàng)建一個(gè)Intent對(duì)象赖歌,并使用該Intent對(duì)象對(duì)外發(fā)送了一條廣播。

發(fā)送了廣播功茴,就得接收廣播庐冯,接收廣播代碼如下:

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        String[] msg = intent.getStringArrayExtra("msg");
        Toast.makeText(context, "接收的Intent的Action為:" + action + "\n消息內(nèi)容是" + msg, Toast.LENGTH_SHORT).show();
    }
}

當(dāng)符合該MyReceiver的廣播出現(xiàn)時(shí),MyReceiver的onReceiver()方法就會(huì)被觸發(fā)坎穿,從而在該方法中顯示廣播所攜帶的消息展父。

發(fā)送廣播時(shí)Intent的Action為com.trampcr.musicplayer.PLAY_ACTION,這就需要配置MyReceiver應(yīng)監(jiān)聽(tīng)Action為該字符串的Intent玲昧,在AndroidManifest.xml中配置:

<receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="com.trampcr.musicplayer.PLAY_ACTION"/>
            </intent-filter>
</receiver>

點(diǎn)擊發(fā)送廣播按鈕栖茉,可以看到收到廣播的提示,如下:

廣播類型


廣播分為兩種:

  • Normal Broadcast(普通廣播):完全異步孵延,可以在同一時(shí)刻被所有接收者接收到吕漂。
    • sendBroadcast():發(fā)送Normal Broadcast。
  • Ordered Broadcast(有序廣播):接收者按預(yù)先聲明的優(yōu)先級(jí)依次接收Broadcast尘应。
    • 優(yōu)先級(jí)聲明在<intent-filter.../>元素的android:priority屬性中惶凝,數(shù)越大優(yōu)先級(jí)越高。
    • Ordered Broadcast接收者可以調(diào)用abortBroadcast()方法終止Broadcast Intent的傳播犬钢,一旦終止苍鲜,后面的接收者就無(wú)法接收到Broadcast。
    • sendOrderedBroadcast():發(fā)送Ordered Broadcast玷犹。

上面發(fā)送廣播中舉了一個(gè)發(fā)送普通廣播的例子混滔,這里再舉一個(gè)發(fā)送有序分廣播的例子:

該程序的Activity界面只有一個(gè)按鈕,用于發(fā)送一條有序廣播歹颓,代碼如下:

public class MainActivity extends AppCompatActivity {

    private Button mSendBroadcast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSendBroadcast = (Button) findViewById(R.id.send_broadcast);

        mSendBroadcast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                //設(shè)置Intent的Action屬性
                intent.setAction("com.trampcr.musicplayer.PLAY_ACTION");
                intent.putExtra("msg", "simple message");
                //發(fā)送有序廣播
                sendOrderedBroadcast(intent, null);
            }
        });
    }
}

代碼中指定了Intent的Action屬性坯屿,再調(diào)用sendOrderedBroadcast()方法來(lái)發(fā)送有序廣播。對(duì)于有序廣播晴股,它會(huì)按優(yōu)先級(jí)依次觸發(fā)每個(gè)BroadcastReceiver的onReceiver()方法愿伴。

第一個(gè)BroadcastReceiver代碼:

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        String msg = intent.getStringExtra("msg");
        Toast.makeText(context, "接收的Intent的Action為:" + action + "\n消息內(nèi)容是" + msg, Toast.LENGTH_SHORT).show();
        //創(chuàng)建一個(gè)Bundle對(duì)象,并存入數(shù)據(jù)
        Bundle bundle = new Bundle();
        bundle.putString("first", "第一個(gè)BroadcastReceiver存入的消息");
        //將bundle放入結(jié)果中
        setResultExtras(bundle);
        //取消Broadcast的繼續(xù)傳播
        //abortBroadcast();
    }
}

MyReceiver不僅處理了它所接收的消息电湘,而且向處理結(jié)果中存入了key為first的消息隔节,這個(gè)消息將可以被第二個(gè)BroadcastReceiver解析出來(lái)。

abortBroadcast()用于取消廣播寂呛,如果這條代碼生效怎诫,那么優(yōu)先級(jí)比MyReceiver低的BroadcastReceiver都將不會(huì)被觸發(fā)。

在AndroidManifest.xml中部署該BroadcastReceiver贷痪,并指定其優(yōu)先級(jí)為20幻妓,代碼如下:

<receiver android:name=".MyReceiver">
            <intent-filter android:priority="20">
                <action android:name="com.trampcr.musicplayer.PLAY_ACTION"/>
            </intent-filter>
</receiver>

接下來(lái)提供第二個(gè)BroadcastReceiver,將會(huì)解析前一個(gè)BroadcastReceiver存入的key為first的消息劫拢,代碼如下:

public class MyReceiver2 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = getResultExtras(true);
        //解析前一個(gè)BroadcastReceiver所存入的key為first的消息
        String first = bundle.getString("first");
        Toast.makeText(context, "第一個(gè)Broadcast存入的消息為:" + first, Toast.LENGTH_SHORT).show();
    }
}

解析出前一個(gè)BroadcastReceiver存入結(jié)果中的key為first的消息肉津。

在AndroidManifest.xml中配置MyReceiver2的優(yōu)先級(jí)為0强胰,如下:

<receiver android:name=".MyReceiver2">
            <intent-filter android:priority="0">
                <action android:name="com.trampcr.musicplayer.PLAY_ACTION" />
            </intent-filter>
</receiver>

先注釋掉abortBroadcast(),點(diǎn)擊發(fā)送有序廣播按鈕妹沙,可以看到先顯示第一個(gè)廣播接收器中的內(nèi)容偶洋,再顯示第二個(gè)廣播接收器中的內(nèi)容,如下:

如果不注釋abortBroadcast()距糖,將會(huì)阻止消息廣播玄窝,消息將傳不到MyReceiver2。

系統(tǒng)廣播


廣播接收器除了可以接收用戶發(fā)送的廣播悍引,還可以接收系統(tǒng)廣播恩脂,常用的系統(tǒng)廣播如下:

  • ACTION_TIME_CHANGED:系統(tǒng)時(shí)間被改變。
  • ACTION_DATE_CHANGED:系統(tǒng)日期被改變趣斤。
  • ACTION_TIMEZONE_CHANGED:系統(tǒng)時(shí)區(qū)被改變俩块。
  • ACTION_BOOT_COMPLETED:系統(tǒng)啟動(dòng)完成。
  • ACTION_PACKAGE_ADDED:系統(tǒng)添加包唬渗。
  • ACTION_PACKAGE_CHANGED:系統(tǒng)的包改變典阵。
  • ACTION_PACKAGE_REMOVED:系統(tǒng)的包被刪除。
  • ACTION_PACKAGE_RESTARTED:系統(tǒng)的包被重啟镊逝。
  • ACTION_PACKAGE_DATA_CLEARED:系統(tǒng)的包數(shù)據(jù)被清空。
  • ACTION_BATTERY_CHANGED:電池電量改變嫉鲸。
  • ACTION_BATTERY_LOW:電池電量低撑蒜。
  • ACTION_POWER_CONNECTED:系統(tǒng)連接電源。
  • ACTION_POWER_DISCONNECTED:系統(tǒng)與電源斷開(kāi)玄渗。
  • ACTION_SHUTDOWN:系統(tǒng)被關(guān)閉座菠。

基于Service的音樂(lè)播放器


這里開(kāi)發(fā)一個(gè)基于Service的音樂(lè)播放器,音樂(lè)由后臺(tái)運(yùn)行的Service負(fù)責(zé)播放藤树,當(dāng)后臺(tái)的播放狀態(tài)發(fā)生變化時(shí)浴滴,程序?qū)?huì)通過(guò)發(fā)送廣播通知前臺(tái)Activity更新界面;當(dāng)點(diǎn)擊Activity的界面按鈕時(shí)岁钓,系統(tǒng)將通過(guò)發(fā)送廣播通知后臺(tái)Service來(lái)改變播放狀態(tài)升略。

前臺(tái)Activity界面有兩個(gè)按鈕,分別用于控制播放/暫停屡限、停止品嚣,另外還有兩個(gè)文本框,用于顯示正在播放的歌曲名钧大、歌手名翰撑。前臺(tái)Activity的代碼如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private ImageButton mStart;
    private ImageButton mStop;
    private TextView mMusicName;
    private TextView mSongerName;
    private ActivityReceiver mActivityReceiver;
    public static final String CTL_ACTION = "com.trampcr.action.CTL_ACTION";
    public static final String UPDATE_ACTION = "com.trampcr.action.UPDATE_ACTION";

    //定義音樂(lè)播放狀態(tài),0x11代表沒(méi)有播放啊央,0x12代表正在播放眶诈,0x13代表暫停
    int status = 0x11;
    String[] musicNames = new String[]{"完美生活", "那一年", "故鄉(xiāng)"};
    String[] songerNames = new String[]{"許巍", "許巍", "許巍"};


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mStart = (ImageButton) findViewById(R.id.start);
        mStop = (ImageButton) findViewById(R.id.stop);
        mMusicName = (TextView) findViewById(R.id.music_name);
        mSongerName = (TextView) findViewById(R.id.songer_name);

        mStart.setOnClickListener(this);
        mStop.setOnClickListener(this);

        mActivityReceiver = new ActivityReceiver();
        //創(chuàng)建IntentFilter
        IntentFilter filter = new IntentFilter();
        //指定BroadcastReceiver監(jiān)聽(tīng)的Action
        filter.addAction(UPDATE_ACTION);
        //注冊(cè)BroadcastReceiver
        registerReceiver(mActivityReceiver, filter);

        Intent intent = new Intent(MainActivity.this, MusicService.class);
        //啟動(dòng)后臺(tái)Service
        startService(intent);
    }

    public class ActivityReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //獲取Intent中的update消息涨醋,update代表播放狀態(tài)
            int update = intent.getIntExtra("update", -1);
            //獲取Intent中的current消息,current代表當(dāng)前正在播放的歌曲
            int current = intent.getIntExtra("current", -1);
            if (current >= 0){
                mMusicName.setText(musicNames[current]);
                mSongerName.setText(songerNames[current]);
            }
            switch (update){
                case 0x11:
                    mStart.setBackgroundResource(R.drawable.play);
                    status = 0x11;
                    break;
                //控制系統(tǒng)進(jìn)入播放狀態(tài)
                case 0x12:
                    //在播放狀態(tài)下設(shè)置使用暫停圖標(biāo)
                    mStart.setBackgroundResource(R.drawable.pause);
                    status = 0x12;
                    break;
                case 0x13:
                    //在暫停狀態(tài)下設(shè)置使用播放圖標(biāo)
                    mStart.setBackgroundResource(R.drawable.play);
                    status = 0x13;
                    break;
            }
        }
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(CTL_ACTION);
        switch (v.getId()){
            case R.id.start:
                intent.putExtra("control", 1);
                break;
            case R.id.stop:
                intent.putExtra("control", 2);
                break;
        }
        //發(fā)送廣播逝撬,將被Service中的BroadcastReceiver接收到
        sendBroadcast(intent);
    }
}

ActivityReceiver()用于響應(yīng)后臺(tái)Service所發(fā)出的廣播东帅,該程序?qū)?huì)根據(jù)廣播Intent里的消息來(lái)改變播放狀態(tài),并更新程序界面中按鈕的圖標(biāo)球拦。

onClick中根據(jù)點(diǎn)擊的按鈕發(fā)送廣播靠闭,發(fā)送廣播時(shí)會(huì)把所按下的按鈕標(biāo)識(shí)發(fā)送出來(lái)。

接下來(lái)是后臺(tái)Service坎炼,會(huì)在播放狀態(tài)發(fā)生改變時(shí)對(duì)外發(fā)送廣播愧膀。代碼如下:

public class MusicService extends Service {

    MyReceiver serviceReceiver;
    AssetManager mAssetManager;
    String[] musics = new String[]{"prefectLife.mp3", "thatYear.mp3", "country.mp3"};
    MediaPlayer mMediaPlayer;
    int status = 0x11;
    int current = 0; // 記錄當(dāng)前正在播放的音樂(lè)

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mAssetManager = getAssets();
        serviceReceiver = new MyReceiver();
        //創(chuàng)建IntentFilter
        IntentFilter filter = new IntentFilter();
        filter.addAction(MainActivity.CTL_ACTION);
        registerReceiver(serviceReceiver, filter);
        //創(chuàng)建MediaPlayer
        mMediaPlayer = new MediaPlayer();
        //為MediaPlayer播放完成事件綁定監(jiān)聽(tīng)器
        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                current++;
                if (current >= 3) {
                    current = 0;
                }
                //發(fā)送廣播通知Activity更改文本框
                Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
                sendIntent.putExtra("current", current);
                //發(fā)送廣播,將被Activity中的BroadcastReceiver接收到
                sendBroadcast(sendIntent);
                //準(zhǔn)備并播放音樂(lè)
                prepareAndPlay(musics[current]);
            }
        });
    }

    public class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int control = intent.getIntExtra("control", -1);
            switch (control){
                case 1: // 播放或暫停
                    //原來(lái)處于沒(méi)有播放狀態(tài)
                    if (status ==0x11){
                        //準(zhǔn)備播放音樂(lè)
                        prepareAndPlay(musics[current]);
                        status = 0x12;
                    }
                    //原來(lái)處于播放狀態(tài)
                    else if (status == 0x12){
                        //暫停
                        mMediaPlayer.pause();
                        status = 0x13; // 改變?yōu)闀和顟B(tài)
                    }
                    //原來(lái)處于暫停狀態(tài)
                    else if (status == 0x13){
                        //播放
                        mMediaPlayer.start();
                        status = 0x12; // 改變狀態(tài)
                    }
                    break;
                //停止聲音
                case 2:
                    //如果原來(lái)正在播放或暫停
                    if (status == 0x12 || status == 0x13){
                        //停止播放
                        mMediaPlayer.stop();
                        status = 0x11;
                    }
            }
            //廣播通知Activity更改圖標(biāo)谣光、文本框
            Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
            sendIntent.putExtra("update", status);
            sendIntent.putExtra("current", current);
            //發(fā)送廣播檩淋,將被Activity中的BroadcastReceiver接收到
            sendBroadcast(sendIntent);
        }
    }

    private void prepareAndPlay(String music) {
        try {
            //打開(kāi)指定的音樂(lè)文件
            AssetFileDescriptor assetFileDescriptor = mAssetManager.openFd(music);
            mMediaPlayer.reset();
            //使用MediaPlayer加載指定的聲音文件
            mMediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
            mMediaPlayer.prepare(); // 準(zhǔn)備聲音
            mMediaPlayer.start(); // 播放
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

MyReceiver用于接收前臺(tái)Activity所發(fā)出的廣播,并根據(jù)廣播的消息內(nèi)容改變Service的播放狀態(tài)萄金,當(dāng)播放狀態(tài)改變時(shí)蟀悦,該Service對(duì)外發(fā)送一條廣播,廣播消息將會(huì)被前臺(tái)Activity接收氧敢,前臺(tái)Activity將會(huì)根據(jù)廣播消息更新界面日戈。

為了讓該音樂(lè)播放器能按順序依次播放歌曲,程序?yàn)镸ediaPlayer增加了OnCompletionListener監(jiān)聽(tīng)器孙乖,當(dāng)MediaPlayer播放完成后將自動(dòng)播放下一首歌曲浙炼。

運(yùn)行程序,效果圖如下:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唯袄,一起剝皮案震驚了整個(gè)濱河市弯屈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恋拷,老刑警劉巖资厉,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蔬顾,居然都是意外死亡宴偿,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門阎抒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)酪我,“玉大人,你說(shuō)我怎么就攤上這事且叁《伎蓿” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)欺矫。 經(jīng)常有香客問(wèn)我纱新,道長(zhǎng),這世上最難降的妖魔是什么穆趴? 我笑而不...
    開(kāi)封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任脸爱,我火速辦了婚禮,結(jié)果婚禮上未妹,老公的妹妹穿的比我還像新娘簿废。我一直安慰自己,他們只是感情好络它,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布族檬。 她就那樣靜靜地躺著,像睡著了一般化戳。 火紅的嫁衣襯著肌膚如雪单料。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天点楼,我揣著相機(jī)與錄音扫尖,去河邊找鬼。 笑死掠廓,一個(gè)胖子當(dāng)著我的面吹牛换怖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播却盘,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼狰域,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了黄橘?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤屈溉,失蹤者是張志新(化名)和其女友劉穎塞关,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體子巾,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帆赢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了线梗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椰于。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖仪搔,靈堂內(nèi)的尸體忽然破棺而出瘾婿,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布偏陪,位于F島的核電站抢呆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏笛谦。R本人自食惡果不足惜抱虐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望饥脑。 院中可真熱鬧恳邀,春花似錦、人聲如沸灶轰。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)框往。三九已至鳄抒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間椰弊,已是汗流浹背许溅。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秉版,地道東北人贤重。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像清焕,于是被迫代替她去往敵國(guó)和親并蝗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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