最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

第六章 組件通訊與廣播消息( 普通廣播、有序廣播、粘性廣播、本地廣播

2018-11-09 23:34 作者:swiss126  | 我要投稿

?參考資料:

《Android應(yīng)用程序開發(fā)》ISBN 9787302283164

參考軟件:

Android Studio、Eclipse+ADT、Android SDK、JDK

普通廣播

普通廣播是完全異步執(zhí)行的廣播。該廣播沒有任何的順序可言,因此效率比較高。也意味著它無法被截斷。廣播的工作流程如下:?

?

廣播之間不能傳遞數(shù)據(jù),不能終止廣播

這是一種不需要考慮接收者接收順序的廣播,比如說有3個接收機,都關(guān)注custom.action.mybroadcast這種廣播,無所謂誰先收到誰后收到。接收機不能阻止其它接收機獲取到這條廣播。

(1)、我們創(chuàng)建一個名為GostBroadcast的類繼承BroadcastReceiver,實現(xiàn)一個自定義的廣播。

?

??public?class?GostBroadcast?extends?BroadcastReceiver?{??

??????@Override??

??????public?void?onReceive(Context?context,?Intent?intent)?{??

??????????String?data?=?intent.getStringExtra("data");??

??????????Toast.makeText(context,?data?+?"/cast",?Toast.LENGTH_LONG).show();??

??????}??

??}??

(2)、注冊廣播,我們注冊一個應(yīng)用程序級別的廣播,在manifest文件中進行注冊。注意在注冊廣播的時候需要指定該廣播的action

??<receiver?android:name="com.dsw.servicedemo.GostBroadcast"??

??????????????android:exported="false">??

??????????????<intent-filter>??

??????????????????<action?android:name="com.dsw.send"/>??

??????????????</intent-filter>??

??</receiver>??

(3)、發(fā)送廣播,通過Intent進行廣播的啟動發(fā)送。

??Intent?intent?=?new?Intent(); ?

??intent.setAction("com.dsw.send");??

??intent.putExtra("data",?"data");??

??sendBroadcast(intent);??

通過這樣一個流程,我們就完成了一個廣播從創(chuàng)建、發(fā)送、接收處理的整個過程。最后在頁面彈出Toast展示我們傳遞的數(shù)據(jù)。

有序廣播

有序廣播是同步執(zhí)行的,廣播可以被中斷。??

有序廣播是用sendOrderedBroadcast來發(fā)送。高優(yōu)先級的接收者會先接收到廣播,然后它可以決定是否繼續(xù)轉(zhuǎn)發(fā),讓低優(yōu)先級的接收者接收到,或者終止廣播。高優(yōu)先級的接收者可以通過setResult把一些信息傳給下一個接收者,下一個接收者則通過getResult獲取上一個接收者傳過來的信息。這個優(yōu)先級也是用android:priority來設(shè)置,范圍是-1000到1000。

這是一種需要考慮接收者接收順序的廣播,比如說有3個接收機,都關(guān)注custom.action.mybroadcast這種廣播,那么安卓系統(tǒng)將根據(jù)這3個接收機聲明的優(yōu)先級進行廣播的投遞。

而且有序廣播是可以被阻截的。

比如,一個廣播按照順序傳遞給3個接收機-A B C,但是B將廣播攔截了,因此C將不會收到這個廣播。

1?發(fā)送

Intent?i?=?new?Intent("custom.action.mybroadcast");

sendOrderedBroadcast(i,?null);

2?接收

接收的時候,需要給intent-filter標(biāo)簽設(shè)置android:priority屬性,表示這個接收機的優(yōu)先級。優(yōu)先級從-1000到1000,數(shù)值越大,優(yōu)先級越高。

<receiver

???android:name=".MyReceiver"

???android:enabled="true"

???android:exported="true">

???<intent-filterandroid:priority="1000">

???????<actionandroid:name="custom.action.mybroadcast"/>

???????<categoryandroid:name="android.intent.category.DEFAULT"?/>

???</intent-filter>

</receiver>

接收到廣播以后,Broadcast Receiver可以將廣播攔截,禁止它往下傳播,

publicclassMyReceiverextendsBroadcastReceiver?{

???publicMyReceiver()?{

???}

???//實現(xiàn)onReceive接口

???@Override

???publicvoidonReceive(Context?context,?Intent?intent)?{

???????//禁止往下傳播

???????abortBroadcast();

???}

}

如果接收機1在onReceive()中,希望把數(shù)據(jù)傳遞給下個接收機2,

接收機1可以使用setResultExtras()方法,

publicclassMyReceiver1extendsBroadcastReceiver?{

????publicMyReceiver()?{

????}

????@Override

????publicvoidonReceive(Context?context,?Intent?intent)?{

????????Bundle?b?=?new?Bundle();

????????b.putString("data",?"this?data?from?MyReceiver");

????????setResultExtras(b);

????}

}

接收機2中,

publicclassMyReceiver2extendsBroadcastReceiver?{

????publicMyReceiver2()?{

????}

????@Override

????publicvoidonReceive(Context?context,?Intent?intent)?{

????????Bundle?b?=?getResultExtras(true);

????????if(b!=null)

????????{

????????????//data就是前一個接收機1傳來的-this?data?from?MyReceiver

????????????String?data?=?b.getString("data");

????????}

????}

}

假如希望將數(shù)據(jù)放到onReceive()傳入的Intent當(dāng)中,是不會傳遞成功的,

@Override

publicvoidonReceive(Context?context,?Intent?intent)?{

????//這是不會成功的

????intent.putExtra("data",?"this?data?from?MyReceiver");

}

傳遞數(shù)據(jù),一定要通過BroadcastReceiver提供的setResultExtras()方法。

粘性廣播

在Android系統(tǒng)粘性廣播一般用來確保重要的狀態(tài)改變后的信息被持久保存,并且能隨時廣播給新的廣播接收器,比如電源的改變,因為耗電需要一個過程,前一個過程必須提前得到,否則可能遇到下次剛好接收到的廣播后系統(tǒng)自動關(guān)機了,隨之而來的是kill行為,所以對某些未處理完的任務(wù)來說,后果很嚴重。

發(fā)送粘性廣播需要權(quán)限(這里的權(quán)限是保存信息的權(quán)限和由系統(tǒng)發(fā)送未處理的廣播的權(quán)限)

<uses-permission?android:name="android.permission.BROADCAST_STICKY"?/>

對于粘性廣播的發(fā)送,和普通廣播的發(fā)送方式是一致的。為了測試粘性廣播的正確使用方式,我們需要定義一個SenderActivity來發(fā)送stick Broadcast

public?class?SenderActivity{@Overrideprotected?void?onCreate(Bundle?saveInstance)?{????super.onCreate(saveInstance);????setContentView(R.layout.stcik_test_layout);????getWindow().setBackgroundDrawableResource(R.drawable.avatar11);}@Overrideprotected?void?onResume()?{????super.onResume();getWindow().getDecorView().postDelayed(new?Runnable()?{????@Override????????public?void?run()?{?????sendStickyBroadcast();??????}????},?3*1000);}private?void?sendStickyBroadcast(){????Intent?i?=?new?Intent();????i.setAction(StickyBroadcastReceiver.Action);????i.putExtra("info",?"sticky?broadcast?has?been?receiver");????sendStickyBroadcast(i);????Log.i("Other","sticky?broadcast?send?ok!");}}

需要知道的是粘性廣播是普通廣播的一種,因此也可以使用普通廣播接收器來接收,當(dāng)然粘性廣播還有另一種常用的接收方式。

1.使用普通廣播接收器,注意,必須在Manifiest或者發(fā)送之前接收(這和定義有點違背,因為這種方式不是正確的接收方式)

public?class?StickyBroadcastReceiver?extends?BroadcastReceiver?{????public?static?final?String?Action?=?"com.sample.test.sticky.broadcast.receiver";????public?static?final?String?PERMISSION?=?"com.sample.test.permission.sticky.receiver";????@Override????public?void?onReceive(Context?context,?Intent?intent)????{????????int?checkCallingOrSelfPermission?=?context.checkCallingOrSelfPermission(PERMISSION);????????if(PackageManager.PERMISSION_GRANTED?==?checkCallingOrSelfPermission)?//權(quán)限判斷????????{????????????Toast.makeText(context,?"授權(quán)成功",?Toast.LENGTH_SHORT).show();????????}else{????????????Toast.makeText(context,?"授權(quán)失敗",?Toast.LENGTH_SHORT).show();????????????throw?new?RuntimeException("permission?denied");????????}????????if(intent!=null&&Action.equals(intent.getAction()))????????{????????????Toast.makeText(context,?intent.getStringExtra("info"),?Toast.LENGTH_SHORT).show();????????}????}}

Mainifest.xml

<!--自定義權(quán)限--><permission?android:name="com.sample.test.permission.sticky.receiver"?android:protectionLevel="normal"?/><!--使用自定義權(quán)限--><uses-permission?android:name="com.sample.test.permission.sticky.receiver"/><!--使用粘性廣播發(fā)送權(quán)限--><uses-permission?android:name="android.permission.BROADCAST_STICKY"?/><!--省略一部分--><receiver?android:name="test.view.weitop.home.StickyBroadcastReceiver"????android:permission="com.sample.test.permission.sticky.receiver"?>????<!--android:permission?其他應(yīng)用使用時,需要檢測的權(quán)限-->????<intent-filter?>?????????<action?android:name="com.sample.test.sticky.broadcast.receiver"/>????</intent-filter></receiver>

2.使用正確的方式接收(推薦)

正確的接收方式不應(yīng)該使用BroadcastReceiver就可以接收到

只需要將SenderActivity的onResume稍作修改即可

@Overrideprotected?void?onResume()?{????super.onResume();//3秒后發(fā)送?getWindow().getDecorView().postDelayed(new?Runnable()?{????@Override????????public?void?run()?????????{?????????sendStickyBroadcast();??????}????},?3*1000);//15秒后就收getWindow().getDecorView().postDelayed(new?Runnable()?{????@Override????public?void?run()????{????????IntentFilter?intentFilter?=?new?IntentFilter(StickyBroadcastReceiver.Action);????????Intent?data?=?registerReceiver(null,?intentFilter);????????if(data!=null&&StickyBroadcastReceiver.Action.equals(data.getAction()))????????{????????????Toast.makeText(this,?data.getStringExtra("info"),?Toast.LENGTH_SHORT).show();????????}????}????},?15*1000);}

在這樣一個相差10秒左右的時間段 【先發(fā)送,后接收】,說明了粘性廣播的已經(jīng)將信息完全保存起來了,只要我們?nèi)ナ褂萌缦路绞?,即可獲取到,而且無限次獲取。

?Intent?data?=?registerReceiver(null,?intentFilter);?//注意,不需要接收器,否則可能無法接收到

附注:這種廣播也可以被移除 ,我們可以接收到 廣播后調(diào)用 removeStickyBroadcast(intent);

本地廣播

? ? 前面所發(fā)送和接收的所用廣播都屬于系統(tǒng)的全局廣播,我們發(fā)出的這些廣播可以給系統(tǒng)中任何應(yīng)用程序接收到,當(dāng)然我們也可以接受其他應(yīng)用程序的廣播。但是,只用本地廣播機制發(fā)出的廣播只能在本應(yīng)用程序中接收到。這樣的話安全性得到了提升。本地廣播機制主要是用LocalBroadcastManager來管理,它提供了發(fā)送廣播的方法sendBroadcast()和sendBroadcastSync()(這也方法好像用的不多,我暫時沒有深究,等以后真正用到可以查一下),注冊接收者的方法registerReceiver(localReceiver, localIntentTilter),需要兩個參數(shù),取消注冊的方法localBroadcastManager.unregisterReceiver(localReceiver);

下面看一下本地廣播機制的工作流程:
1.發(fā)送本地廣播

?//發(fā)送本地廣播localBroadcastManager?=?LocalBroadcastManager.getInstance(this);?//獲取本地廣播管理實例localCastBtn?=?(Button)?findViewById(R.id.local_btn);localCastBtn.setOnClickListener(new?View.OnClickListener()?{????@Override????public?void?onClick(View?v)?{????????//發(fā)送本地廣播????????Intent?intent?=?new?Intent("com.zwf.broadcastdemo.LOCAL_BROADCAST");????????localBroadcastManager.sendBroadcast(intent);????}});

2.注冊廣播接收者

//注冊本地廣播監(jiān)聽localIntentTilter?=?new?IntentFilter("com.zwf.broadcastdemo.LOCAL_BROADCAST");localReceiver?=?new?LocalReceiver();localBroadcastManager.registerReceiver(localReceiver,?localIntentTilter);

3.取消注冊

//取消本地廣播監(jiān)聽localBroadcastManager.unregisterReceiver(localReceiver);

使用本地廣播的優(yōu)勢?
1. 可以明確地知道正在發(fā)送的廣播不會離開本程序,因此不需要擔(dān)心機密數(shù)據(jù)泄漏的問題。?
2. 其他程序無法將廣播發(fā)送到本程序的內(nèi)部,因此不需要擔(dān)心會有安全漏洞的隱患。?
3. 發(fā)送本地廣播比起發(fā)送系統(tǒng)全局廣播將會更加高效。

?


第六章 組件通訊與廣播消息( 普通廣播、有序廣播、粘性廣播、本地廣播的評論 (共 條)

分享到微博請遵守國家法律
南康市| 唐河县| 冕宁县| 蒲城县| 黄梅县| 兰考县| 连城县| 娄底市| 额尔古纳市| 商南县| 贵德县| 卓资县| 隆德县| 日照市| 南汇区| 梨树县| 抚顺市| 库车县| 彝良县| 道孚县| 龙里县| 马龙县| 安多县| 穆棱市| 北京市| 乐都县| 理塘县| 洪江市| 乐东| 浦县| 湖南省| 靖边县| 普宁市| 敦煌市| 封丘县| 炉霍县| 乳山市| 阳曲县| 云阳县| 原阳县| 碌曲县|