5. 全局大喇叭-詳解廣播機(jī)制

03.jpg

第5章 全局大喇叭-詳解廣播機(jī)制

了解網(wǎng)絡(luò)通信原理的應(yīng)該會(huì)知道,在一個(gè)IP網(wǎng)絡(luò)范圍中平项,最大的IP地址是被保留作為廣播地址來使用的。比如某個(gè)網(wǎng)絡(luò)的IP范圍是192.168.0.XXX,子網(wǎng)掩碼是255.255.255.0,那么這個(gè)網(wǎng)絡(luò)的廣播地址就是192.168.0.255。廣播數(shù)據(jù)包會(huì)被發(fā)送到同一網(wǎng)絡(luò)上的所有端口枝笨,這樣在該網(wǎng)絡(luò)中的每臺(tái)主機(jī)都將會(huì)收到這條廣播袁铐。

1.廣播機(jī)制簡介

Android中的每個(gè)應(yīng)用程序都可以對(duì)自己感興趣的廣播進(jìn)行注冊(cè)揭蜒,這樣該程序就只會(huì)接收到自己所關(guān)心的廣播內(nèi)容,這些廣播可能是來自于系統(tǒng)的剔桨,也可能是來自于其他應(yīng)用程序的屉更。Android提供了一套完整的API,允許應(yīng)用程序自由的發(fā)送和接收廣播洒缀。

  • 標(biāo)準(zhǔn)廣播
    是一種完全異步執(zhí)行的廣播瑰谜,在廣播發(fā)出之后,所有的廣播接收器幾乎都會(huì)在同一時(shí)刻接收到這條廣播消息树绩,因此它們之間沒有任何先后順序可言萨脑。這種廣播的效率會(huì)比較高,但同時(shí)也意味著它是無法被截?cái)嗟摹?/p>

  • 有序廣播
    則是一種同步執(zhí)行的廣播饺饭,在廣播發(fā)出之后渤早,同一時(shí)刻只會(huì)有一個(gè)廣播接收器能夠收到這條廣播消息,當(dāng)這個(gè)廣播接收器中的邏輯執(zhí)行完畢后瘫俊,廣播才會(huì)繼續(xù)傳遞鹊杖。所以此時(shí)的廣播接收器是有先后順序的,優(yōu)先級(jí)高的廣播接收器就可以先收到廣播消息扛芽,并且前面的廣播接收器還可以截?cái)嗾趥鬟f的廣播骂蓖,這樣后面的廣播接收器就無法收到廣播消息了。

2.動(dòng)態(tài)注冊(cè)監(jiān)聽網(wǎng)絡(luò)變化

注冊(cè)廣播的方式一般有兩種川尖,在代碼中注冊(cè)和在AndroidManifest.xml中注冊(cè)登下,其中前者被稱為動(dòng)態(tài)注冊(cè),后者被稱為靜態(tài)注冊(cè)空厌。

創(chuàng)建一個(gè)廣播接收器庐船,需要新建一個(gè)類,讓它繼承自BroadcastReceiver,并重寫父類的onReceive()方法就可以了嘲更。

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;

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

        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver,intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }

    class NetworkChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(MainActivity.this, "network changes", Toast.LENGTH_SHORT).show();
        }

    }
}

MainActivity中定義了一個(gè)內(nèi)部類NetworkChangeReceiver,這個(gè)類是繼承自BroadcastReceiver的筐钟,并重寫了父類的onReceive()方法。
onCreate()方法中赋朦,首先我們創(chuàng)建了一個(gè)IntentFilter的實(shí)例,并給它添加一個(gè)值為android.net.conn.CONNECTIVITY_CHANGEaction,我們的廣播接收器想要監(jiān)聽什么廣播宠哄,就在這里添加相應(yīng)的action,接下來創(chuàng)建了一個(gè)NetworkChangeReceiver的實(shí)例壹将,然后調(diào)用registerReceiver()方法進(jìn)行注冊(cè),將NetworkChangeReceiver的實(shí)例和IntentFilter的實(shí)例都傳了進(jìn)去毛嫉,這樣NetworkChangeReceiver就會(huì)收到所有值為android.net.conn.CONNECTIVITY_CHANGE的廣播诽俯。

動(dòng)態(tài)注冊(cè)的廣播接收器一定都要取消注冊(cè)才行,這里我們是在onDestroy()方法中通過調(diào)用unregisterReceiver()方法來實(shí)現(xiàn)的承粤。

class NetworkChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //Toast.makeText(MainActivity.this, "network changes", Toast.LENGTH_SHORT).show();
            ConnectivityManager connectionManager = (ConnectivityManager)
                    getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isAvailable()) {
                Toast.makeText(MainActivity.this, "network is available", Toast.LENGTH_SHORT).show();
            }
            else {
                Toast.makeText(MainActivity.this, "network is unavailable", Toast.LENGTH_SHORT).show();
            }

        }

    }

首先通過getSystemService()方法得到了ConnectivityManager的實(shí)例暴区,這是一個(gè)系統(tǒng)服務(wù)類闯团,專門用于管理網(wǎng)絡(luò)連接的。然后調(diào)用它的getActiveNetworkInfo()方法可以得到NetworkInfo的實(shí)例仙粱,接著調(diào)用NetworkInfoisAvailable()方法房交,就可以判斷出當(dāng)前是否有網(wǎng)絡(luò)了。

Android系統(tǒng)為了保護(hù)用戶設(shè)備的安全和隱私伐割,做了嚴(yán)格的規(guī)定:如果程序需要進(jìn)行一些對(duì)用戶來說比較敏感的操作候味,就必須在配置文件中聲明權(quán)限才可以,否則程序?qū)?huì)直接崩潰隔心。

3.靜態(tài)注冊(cè)實(shí)現(xiàn)開機(jī)啟動(dòng)

動(dòng)態(tài)注冊(cè)的廣播接收器可以自由地控制注冊(cè)和注銷白群,在靈活性方面有很大的優(yōu)勢,但是它也存在著一個(gè)缺點(diǎn)济炎,即必須要在程序啟動(dòng)之后才能接收到廣播川抡,因?yàn)樽?cè)的邏輯是寫在onCreate()方法中的,讓程序在未啟動(dòng)的情況下就能接收到廣播须尚,需要使用靜態(tài)注冊(cè)的方式

image

  • Exported: 表示是否允許這個(gè)廣播接收器接收本程序以外的廣播
  • Enabled: 表示是否啟用這個(gè)廣播接收器

靜態(tài)的廣播接收器一定要在AndroidManifest.xml文件中注冊(cè)才可以使用崖堤。

<receiver
    android:name=".BootCompleteReceiver"
    android:enabled="true"
    android:exported="true">
</receiver>

<application>標(biāo)簽內(nèi)出現(xiàn)了一個(gè)新的標(biāo)簽<receiver>,所有靜態(tài)的廣播接收器都是在這里進(jìn)行注冊(cè)的,它的用法其實(shí)和<activity>標(biāo)簽非常相似耐床,也是通過android:name來指定具體注冊(cè)哪一個(gè)廣播接收器密幔。

<receiver
      android:name=".BootCompleteReceiver"
      android:enabled="true"
      android:exported="true">
      <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
      </intent-filter>
</receiver>

Android系統(tǒng)啟動(dòng)完成后會(huì)發(fā)出一道值為android.intent.action.BOOT_COMPLETED的廣播,因此我們?cè)?code><intent-filter>標(biāo)簽里添加了相應(yīng)的action撩轰。另外胯甩,監(jiān)聽系統(tǒng)開機(jī)廣播也是需要聲明系統(tǒng)權(quán)限的,我們使用<uses-permission>標(biāo)簽又加入了一條android.permission.RECEIVE_BOOT_COMPLETED權(quán)限堪嫂。

需要注意的是偎箫,不要再onReceiver()方法中添加過多的邏輯或者進(jìn)行任何的耗時(shí)操作,因?yàn)樵趶V播接收器中是不允許開啟線程的皆串,當(dāng)onReceive()方法運(yùn)行了較長時(shí)間而沒有結(jié)束時(shí)淹办,程序就會(huì)報(bào)錯(cuò),因此廣播接收器更多的是扮演一種打開程序其他組件的角色恶复,比如創(chuàng)建一條狀態(tài)欄通知怜森,或者啟動(dòng)一個(gè)服務(wù)等。

4.發(fā)送自定義廣播

// 1. 
 public void initView() {
   button.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v){
           Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
           sendBroadcast(intent);
       }
   });
}

// 2.
<receiver
    android:name=".MyBroadcastReceiver"
    android:exported="true"
    android:enabled="true">

    <intent-filter>
        <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
    </intent-filter>

</receiver>

首先構(gòu)建出了一個(gè)Intent對(duì)象谤牡,并把要發(fā)送的廣播的值傳入副硅,然后調(diào)用了ContextsendBroadcast()方法將廣播發(fā)送出去,這樣所有監(jiān)聽com.example.broadcasttest.MY_BROADCAST這條廣播的廣播接收器就會(huì)收到消息翅萤。

廣播是使用Intent進(jìn)行傳遞的恐疲,因此你還可以在Intent中攜帶一些數(shù)據(jù)傳遞給廣播接收器。

發(fā)送有序廣播

廣播是一種可以跨進(jìn)程的通信方式,我們應(yīng)用程序發(fā)出的廣播培己,其他的應(yīng)用程序也是可以收到的糜烹。

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
        sendOrderedBroadcast(intent,null);
    }
});

sendBroadcast()方法改成sendOrderedBroadcast()方法。sendOrderedBroadcast()方法接收兩個(gè)參數(shù)漱凝,第一個(gè)參數(shù)仍然是Intent,第二個(gè)參數(shù)是一個(gè)與權(quán)限相關(guān)的的字符串诸迟,這里傳入null就行了茸炒。

<receiver
    android:name=".AnotherBroadcastReceiver"
    android:exported="true"
    android:enabled="true">

    <intent-filter
        android:priority="100">
        <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
    </intent-filter>

</receiver>

通過android:priority屬性給廣播接收器設(shè)置了優(yōu)先級(jí),優(yōu)先級(jí)比較高的廣播接收器就可以先收到廣播阵苇。

public class AnotherBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received in AnotherBroadcastReceiver", Toast.LENGTH_SHORT).show();
        abortBroadcast();
    }
}

onReceiver()方法中調(diào)用了abortBroadcast()方法壁公,就表示將這條廣播截?cái)啵竺娴膹V播接收器將無法在接收到這條廣播绅项。

5.使用本地廣播

前面我們發(fā)送和接收的廣播全部屬于系統(tǒng)全局廣播紊册,即發(fā)出的廣播可以被其他任何應(yīng)用程序接收到,并且我們也可以接收到來自于其他任何應(yīng)用程序的廣播快耿。
為了能夠簡單地解決廣播的安全性問題囊陡,Android引入了一套本地廣播機(jī)制,使用這個(gè)機(jī)制發(fā)出的廣播只能在應(yīng)用程序的內(nèi)部進(jìn)行傳遞掀亥,并且廣播接收器也只能接收來自本應(yīng)用程序發(fā)出的廣播撞反。
本地廣播主要是使用了一個(gè)LocalBroadcastManager來對(duì)廣播進(jìn)行管理。

public class MainActivity extends AppCompatActivity
{

    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        button = (Button) findViewById(R.id.button);
        initEvent();
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcast.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    public void initEvent()
    {
        button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Intent intent = new Intent("com.example.broadcast.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
    }

    class LocalReceiver extends BroadcastReceiver
    {

        @Override
        public void onReceive(Context context, Intent intent)
        {
            Toast.makeText(context, "received in local broadcast", Toast.LENGTH_SHORT).show();
        }
    }
}

首先是通過LocalBroadcastManager的getInstance()方法得到了一個(gè)他的實(shí)例搪花,然后在注冊(cè)廣播接收器的時(shí)候調(diào)用的是LocalBroadcastManager的sendBroadcast()方法遏片。
另外還有一點(diǎn)需要說明,本地廣播是無法通過靜態(tài)注冊(cè)的方式來接收的撮竿,其實(shí)這也完全可以理解吮便,因?yàn)殪o態(tài)注冊(cè)主要就是為了讓程序在未啟動(dòng)的時(shí)候,也能收到廣播幢踏,而發(fā)送本地廣播時(shí)髓需,我們的程序肯定是已經(jīng)啟動(dòng)了,因此也完全不需要使用靜態(tài)注冊(cè)的功能惑折。
**優(yōu)勢: **
1.可以明確地知道正在發(fā)送的廣播不會(huì)離開我們的程序授账,因此不必?fù)?dān)心機(jī)密數(shù)據(jù)泄露。
2.其他的程序無法將廣播發(fā)送到我們程序的內(nèi)部惨驶,因此不需要擔(dān)心會(huì)有安全漏洞的隱患白热。
3.發(fā)送本地廣播比發(fā)送系統(tǒng)全局廣播將會(huì)更加高效。

6.廣播的最佳實(shí)踐-實(shí)現(xiàn)強(qiáng)制下線功能

實(shí)現(xiàn)強(qiáng)制下線功能的思路比較簡單粗卜,只需要在界面上彈出一個(gè)對(duì)話框屋确,讓用戶無法進(jìn)行其他任何操作,必須要點(diǎn)擊對(duì)話框中的確定按鈕,然后回到登錄界面即可攻臀。
強(qiáng)制下線功能需要先關(guān)閉掉所有的活動(dòng)焕数,然后回到登錄界面。

public class ActivtyCollector
{
    public static List<Activity> activityList = new ArrayList<>();

    public static void addActivity(Activity activity)
    {
        activityList.add(activity);
    }

    public static void removeActivity(Activity activity)
    {
        activityList.remove(activity);
    }

    public static void finishAll()
    {
        for (Activity activity : activityList)
        {
            if (!activity.isFinishing())
            {
                activity.finish();
            }
        }
    }
}

Activity在Destroy之前刨啸,activity.isFinishing返回false堡赔,Activityon在Destroy之后,返回true

public class LoginActivity extends BaseActivity
{
    private Button button;
    private EditText editText_Account,editText_Password;

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

        initView();
        initEvent();
    }

    public void initView()
    {
        button = (Button) findViewById(R.id.button_login);
        editText_Account = (EditText) findViewById(R.id.edit_account);
        editText_Password = (EditText) findViewById(R.id.edit_password);
    }

    public void initEvent()
    {
        button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                String account = editText_Account.getText().toString();
                String password = editText_Password.getText().toString();

                if (account.equals("admin") && password.equals("123456"))
                {
                    Intent intent = new Intent(LoginActivity.this,MainActivity.class);
                    startActivity(intent);
                    finish();
                }
                else
                {
                    Toast.makeText(LoginActivity.this, "輸入的賬號(hào)或密碼有誤I枇I埔选!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

public class MainActivity extends BaseActivity
{

    private Button button;
    public static String Tag = "com.example.broadcastbestpractice_FORCE_OFFLINE";

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

        button = (Button) findViewById(R.id.button_send);
        initEvent();
    }

    public void initEvent()
    {
        button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Intent intent = new Intent(Tag);
                sendBroadcast(intent);
            }
        });
    }
}

MainActivity只是發(fā)送了一個(gè)標(biāo)準(zhǔn)廣播离例。
強(qiáng)制用戶下線的邏輯并不是寫在MainActivity里的换团,而是應(yīng)該寫在接收這條廣播的廣播接收器里面,這樣強(qiáng)制下線的功能就不會(huì)依附于任何的界面宫蛆,不管是在程序的任何地方艘包,只需要發(fā)出一條這樣的廣播,就可以完成強(qiáng)制下線的操作了耀盗。
注冊(cè)的靜態(tài)的廣播接收器想虎,是沒有辦法在onReceive()方法里彈出對(duì)話框這樣的UI控件的,而我們顯然也不可能在每個(gè)活動(dòng)中都去注冊(cè)一個(gè)動(dòng)態(tài)的廣播接收器袍冷。

public class BaseActivity extends AppCompatActivity
{
    private IntentFilter intentFilter;
    private ForceOfflineReceiver forceOfflineReceiver;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        ActivtyCollector.addActivity(this);
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        ActivtyCollector.removeActivity(this);
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        intentFilter = new IntentFilter();
        intentFilter.addAction(MainActivity.Tag);
        forceOfflineReceiver = new ForceOfflineReceiver();
        registerReceiver(forceOfflineReceiver,intentFilter);
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        unregisterReceiver(forceOfflineReceiver);
    }

    class ForceOfflineReceiver extends BroadcastReceiver
    {

        @Override
        public void onReceive(Context context, final Intent intent)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle("警告磷醋!");
            builder.setCancelable(false);
            builder.setMessage("賬號(hào)在別處登錄,你被迫下線胡诗,請(qǐng)重新登錄");
            builder.setPositiveButton("確定", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    ActivtyCollector.finishAll();
                    Intent intent1 = new Intent(BaseActivity.this,LoginActivity.class);
                    startActivity(intent1);
                }
            });
            builder.show();
        }
    }
}

注意這里一定要調(diào)用builder.setCancelable(false)將對(duì)話框設(shè)為不可取消邓线。
我們始終需要保證只有處于棧頂?shù)幕顒?dòng)才能接收到這條強(qiáng)制下線廣播,非棧頂?shù)幕顒?dòng)不應(yīng)該也沒有必要去接收這條廣播煌恢,所以寫在onResume()和onPause()方法里就可以很好的解決這個(gè)問題骇陈,當(dāng)一個(gè)活動(dòng)失去棧頂位置時(shí)就會(huì)自動(dòng)取消廣播接收器的注冊(cè)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瑰抵,一起剝皮案震驚了整個(gè)濱河市你雌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌二汛,老刑警劉巖婿崭,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異肴颊,居然都是意外死亡氓栈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門婿着,熙熙樓的掌柜王于貴愁眉苦臉地迎上來授瘦,“玉大人醋界,你說我怎么就攤上這事√嵬辏” “怎么了形纺?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長徒欣。 經(jīng)常有香客問我逐样,道長,這世上最難降的妖魔是什么打肝? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任官研,我火速辦了婚禮,結(jié)果婚禮上闯睹,老公的妹妹穿的比我還像新娘。我一直安慰自己担神,他們只是感情好楼吃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妄讯,像睡著了一般孩锡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上亥贸,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天躬窜,我揣著相機(jī)與錄音,去河邊找鬼炕置。 笑死荣挨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朴摊。 我是一名探鬼主播默垄,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼甚纲!你這毒婦竟也來了口锭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤介杆,失蹤者是張志新(化名)和其女友劉穎鹃操,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體春哨,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荆隘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了悲靴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臭胜。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡莫其,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耸三,到底是詐尸還是另有隱情乱陡,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布仪壮,位于F島的核電站憨颠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏积锅。R本人自食惡果不足惜爽彤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缚陷。 院中可真熱鬧适篙,春花似錦、人聲如沸箫爷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虎锚。三九已至硫痰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窜护,已是汗流浹背效斑。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柱徙,地道東北人缓屠。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像护侮,于是被迫代替她去往敵國和親藏研。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,761評(píng)論 25 707
  • 為什么說Android中的廣播機(jī)制更加靈活啦概行?這是因?yàn)锳ndroid中的每個(gè)應(yīng)用程序都可以對(duì)自己感興趣...
    AndYMJ閱讀 568評(píng)論 0 1
  • 本篇文章主要介紹以下幾個(gè)知識(shí)點(diǎn):廣播機(jī)制的簡介蠢挡;接收系統(tǒng)廣播:動(dòng)態(tài)注冊(cè)與靜態(tài)注冊(cè);發(fā)送自定義廣播凳忙;使用本地廣播业踏;實(shí)...
    開心wonderful閱讀 1,419評(píng)論 1 7
  • 選題計(jì)劃1:二次元歌手及其身后的粉絲團(tuán)隊(duì) 我所界定的“二次元歌手”,是指在YY語音等軟件的頻道上唱古風(fēng)涧卵、二次元的歌...
    遠(yuǎn)離愛因斯坦閱讀 631評(píng)論 0 0
  • 我發(fā)現(xiàn)我總是在害怕失去 我總是容易做出承諾 明明自己心里已經(jīng)有了答案 卻還是在猶豫不決 明明知道帶來的會(huì)是失望卻總...
    安可果兒閱讀 292評(píng)論 0 3