<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                業精于勤,荒于嬉;行成于思,毀于隨。---韓愈 在Android開發中BroadcastReceiver的使用是非常廣泛的它也是Android的四大組件之一,翻譯成漢語就是:"廣播接收者",那么什么是廣播呢?舉個日常生活的例子,在農村大隊里村干部這里會有一個大喇叭,用來發送廣播通知各種事情,假如由于小花超生通知小花和小明來開會村干部就會通過大喇叭說:”喂,咱莊上的人注意了,小花和小明請以最快的速度來開會"。這個廣播發出之后,首先這個莊上的所有人都聽到了廣播,村民們根據廣播的內容選擇去還是不去,小花和小明聽到廣播后開始分析:"小花和小明去開會,我是小花,我應該去開會"小明也是如此,村民們雖然聽到了廣播,但是分析后發現跟我沒關系啊,于是繼續干自己的事情。這是我們生活中的廣播的形式,那么在android中廣播是怎么一回事呢?一起來揭開它的面紗吧。 Android中的BroadcastReceiver的設計不得不讓人拍案叫絕,它大大減少了開發者的工作量,假如現在要實現功能檢測電池的電量少于10%進入省電模式,如果沒有廣播,我們要設監聽,注冊監聽器,然后處理。這樣是不是很麻煩?用廣播就很爽啊,當電池的電量改變時系統會發出一條廣播我們只需要接收這條廣播然后判斷它是否低于10%就行了。這樣工作量大大的減少了!這只是廣播的一個小的應用,除此之外當手機的網絡變化、手機開機時等系統也會發出一條廣播,我們可以收到此廣播做自己想要的處理 下面我們結合實例來對BroadcastReceiver做詳細的闡述,如有疑問歡迎提問,如有謬誤歡迎批評指正,謝謝 **一、 廣播分類** 1.普通廣播 普通廣播是完全異步的,所謂異步就是說這個廣播可以在同一時刻(邏輯上)被所有廣播接收者接收到,消息傳遞的效率比較高,但缺點是:接收者不能將接收到的數據處理后將處理結果傳遞給下一個接收者,并且無法終止廣播Intent的傳播; 這種廣播的發送方式是:Context.SendBroadcast(); 2.有序廣播 然而有序廣播是按照接收者聲明的優先級別聲明方式如下 ~~~ <receiver? ~~~ ~~~ android:name=".broadcastreceiver.FirstBroadcastReceiver"> <intent-filter android:priority="Integer" > <action android:name="com.example.BroadcastReceiver" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> ~~~ ?在intent-filter元素的android:priority屬性中配置優先級,數越大優先級別越高,取值范圍:-1000到1000。也可以調 用IntentFilter對象的setPriority()進行設置,配置好優先級后當廣播過來時被接收者依次接收廣播。假如現在現在有三個接收者Receiver1、Receiver2、Receiver3 如:Receiver1的級別高于Receiver2,Receiver2的級別高于Receiver3,那么當發送一個有序廣播的時候,廣播會先發給Receiver1,然后再發給Receiver2,最后傳給Receiver3。Receiver1收到廣播后可以對廣播進行處理: (1)可以往廣播里存入數據,當廣播傳給Receiver2時,Receiver2可以從廣播中得到Receiver1存入的數據。 (2)中斷廣播調用BroadcastReceiver.abortBroadcast()這個方法進行廣播的中斷,中斷后Receiver2、Receiver3將收不到此條廣播 這種廣播的發送的方式是:Context.sendOrderedBroadcast(); 按來源分(這是我自己的想的,哈哈) ? ?1.自己定義的廣播 ? ?2.系統廣播就是系統里面自帶的廣播 **二、廣播的注冊方式** 廣播的注冊方式可以分為兩種 1.靜態注冊 這種方式是在AndroidManifest.xml清單文件中注冊的注冊方式如下 ~~~ <receiver android:name = ".broadcastreceiver.FirstBroadcastReceiver"> <intent-filter> < action android:name ="com.example.BroadcastReceiver" /> < category android:name ="android.intent.category.DEFAULT" /> </intent-filter> </receiver> ~~~ 配置了以上信息之后,只要是com.example.BroadcastReceiver這個地址的廣播,廣播接收者都能夠接收的到。注意,這種方式的注冊是常駐型的,也就是說當應用關閉后,如果有廣播信息傳來,廣播接受者也會被系統調用而自動運行。 2.動態注冊 ? 動態注冊需要在代碼中動態的指定廣播地址并注冊,通常我們是在Activity或Service(在服務中監聽網絡的狀態,電量的變化,然后在服務中發出一個廣播)注冊一個廣播, 注:動態注冊的廣播是非常駐型廣播,當應用程序結束了,廣播自然就沒有了,比如你在activity中的onCreate或者onResume中注冊廣播,同時你必須在onDestory或者onPause中取消廣播訂閱。不然會報異常。 注冊廣播的代碼如下 ~~~ FirstBroadcastReceiver firstBroadcastReceiver= new FirstBroadcastReceiver(); IntentFilter intentFilter= new IntentFilter(); intentFilter.addAction( "com.example.BroadcastReceiver" ); registerReceiver(firstBroadcastReceiver,intentFilter); ~~~ 可能有的朋友會問,為什么registerReceiver和SendBroadcastReceiver在Activity和Service中可以直接用,我們看看它們的繼承關系圖: ![](https://box.kancloud.cn/2016-03-01_56d500e1242a3.jpg) ?![](https://box.kancloud.cn/2016-03-01_56d500e13457a.jpg) ![](https://box.kancloud.cn/2016-03-01_56d500e144df7.jpg) ![](https://box.kancloud.cn/2016-03-01_56d500e15a22d.jpg) 通過這四張圖看明白了吧,registerReceiver和sendBroadcast是android.content.ContextWrapper類中的方法,Activity和Service都繼承了ContextWrapper,所以可以直接調用,但是如果我們在其它的類中的話是不可以直接調用的可以通過Conext.sendBroadcast的方式進行調用。 還有一點需要注意,當我們的在Activity或Service中執行了銷毀操作但是沒有解除注冊的話會拋異常,雖然不影響程序的運行,但是作為一名有經驗的開發人員,我們要保證代碼的嚴謹性(說這話沒別的意思,就是裝個B,哈哈)拋出的異常提示是否忘記調用unregisterReceiver()方法了,異常如下 ![](https://box.kancloud.cn/2016-03-01_56d500e16d6c2.jpg) 所以我們要根據需要在合適的地方解除注冊假如我們在onDestroy中解除注冊代碼如下 ~~~ @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver( firstBroadcastReceiver ); } ~~~ 下面我們通過實例來對上面的理論進行測試,來進一步的加深印象,看看廣播是怎么發出的,是怎么被接收的 **三、BroadCastReceiver實例詳解** 1.關于靜態和動態注冊廣播的討論 首先創建BroadcastReceiver 在創建BroadcastReceiver時需要聲明一個類來繼承android.content.BroadcastReceiver包下的BroadcastReceiver并且復寫其中的onReceive方法示例代碼 ~~~ package com.example.broadcastreceiverpractice.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class FirstBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "FirstBroadcastReceiver" ; @Override public void onReceive(Context context, Intent intent) { String getFromBroadcast = intent.getStringExtra("key" ); Log. i( TAG,getFromBroadcast); } } ~~~ 在onReceive方法中我們通過獲得廣播傳過來的數據來進行測試是否收到了我們所需要的廣播,進行到這兒還有更重要的一步,那就是注冊廣播假如我們不注冊廣播的話,我們想向這個廣播接收者發消息的話就無法發送,因為找不到和這個廣播對應的東西,注冊廣播可以分為兩種上面已經提到了我們再來通過實例說一遍 ~~~ <receiver android:name =".broadcastreceiver.FirstBroadcastReceiver" > <intent-filter> <action android:name ="com.example.BroadcastReceiver" /> <category android:name ="android.intent.category.DEFAULT" /> </intent-filter> </receiver> ~~~ 配置以上內容的作用就是說從當前Receiver只接收從com.example.BroadcastReceiver發過來的廣播,這樣廣播發送者和接收者就建立了聯系了。當從com.example.BroadcastReceiver發出廣播時系統就會自動調用這個廣播接收者來進行相關的操作 說了這么多我們在Activity中測試一下吧 ~~~ package com.example.broadcastreceiverpractice; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { private Button btn_send; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); btn_send=(Button) findViewById(R.id. btn_send); btn_send.setOnClickListener( new OnClickListener() { public void onClick(View v) { //發送一條廣播com.example.BroadcastReceiver要和廣播接收者在清單文件中配置的相同 Intent intent = new Intent("com.example.BroadcastReceiver" ); intent.putExtra( "key", "MainActivity中發了一條廣播" ); sendBroadcast(intent); } }); } } ~~~ 我們點擊幾次發送按鈕在廣播接收者中打印內容如下 ![](https://box.kancloud.cn/2016-03-01_56d500e1812cc.jpg) 說明我們已經接收到了廣播 (2)動態注冊 在原來的基礎上我們把AndroidManifest.xml清單文件中的靜態的注冊的代碼去掉 只去掉<intent-filter></intent-filter>之間的內容即可,廣播接收者是四大組件我們必須注冊,大家要把廣播接收者是四大組件之一的注冊和為了接收自己設定的地址發過來的廣播而進行的注冊區分開。 ~~~ package com.example.broadcastreceiverpractice; import com.example.broadcastreceiverpractice.broadcastreceiver.FirstBroadcastReceiver; import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { private Button btn_send; private FirstBroadcastReceiver firstBroadcastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); firstBroadcastReceiver = new FirstBroadcastReceiver(); //聲明過濾器 IntentFilter intentFilter= new IntentFilter(); intentFilter.addAction( "com.example.BroadcastReceiver" ); //將添加的動作和聲明的廣播接收者綁定到一起,和我們在清單文件中配置的作用是一樣的 registerReceiver( firstBroadcastReceiver,intentFilter); btn_send=(Button) findViewById(R.id. btn_send); btn_send.setOnClickListener( new OnClickListener() { public void onClick(View v) { //發送一條廣播com.example.BroadcastReceiver要和廣播接收者在清單文件中配置的相同 Intent intent = new Intent("com.example.BroadcastReceiver" ); intent.putExtra( "key", "MainActivity中發了一條廣播" ); sendBroadcast(intent); } }); } @Override protected void onDestroy() { super.onDestroy(); //解除注冊 unregisterReceiver( firstBroadcastReceiver); } } ~~~ 我們點擊幾次按鈕發送廣播打印內容如下 ![](https://box.kancloud.cn/2016-03-01_56d500e1919dc.jpg) 關于動態注冊廣播的特點以及注意事項在"二"中已經說了,這里就不再重復說了唯一要提的一點就是別忘了解除注冊。 但是問題來了,上面只是一個廣播,假如我們我們有多個廣播呢,誰先接收呢,能同時接收嗎等等問題,要想弄清這個問題必須掌握普通廣播和有序廣播 2.有序廣播和普通廣播 (1)普通廣播 要討論這個問題你我們首先新建三個廣播 分別如下 ~~~ package com.example.broadcastreceiverpractice.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class FirstBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "FirstBroadcastReceiver" ; @Override public void onReceive(Context context, Intent intent) { String getFromBroadcast = intent.getStringExtra("key" ); Log. i( TAG,getFromBroadcast); } } ~~~ ~~~ package com.example.broadcastreceiverpractice.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class SecondBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "SecondBroadcastReceiver" ; @Override public void onReceive(Context context, Intent intent) { String getFromBroadcast = intent.getStringExtra("key" ); Log. i( TAG,getFromBroadcast); } } ~~~ ~~~ package com.example.broadcastreceiverpractice.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class ThirdBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "ThirdBroadcastReceiver" ; @Override public void onReceive(Context context, Intent intent) { String getFromBroadcast = intent.getStringExtra("key" ); Log. i( TAG,getFromBroadcast); } } ~~~ 以上三個廣播接收者都采用的是靜態注冊在清單文件中進行注冊,然后在MainActivity中點擊發送廣播按鈕打印日志如下 ![](https://box.kancloud.cn/2016-03-01_56d500e1a020e.jpg) 我們看到都收到了,我們再看下時間差那么幾毫秒,這個接收順序跟我們在清單文件中配置的順序是一致的,假如我們把SecondBroadcastReceiver方法最上面FirstBroadcastReceiver放在第二那么打印日志如下 ![](https://box.kancloud.cn/2016-03-01_56d500e1b0c0f.jpg) 說明這三個接收者都接收到了廣播。 接著我們試著來中斷這個廣播在每個接收者的的onReceive()方法中來中斷廣播添加如下代碼 ~~~ abortBroadcast(); ~~~ 然后點擊發送按鈕發現每個接收者都能接收到廣播,說明這種廣播是不能被終止的 (2)有序廣播 有序廣播比較特殊當我們調用Context.sendOrderedBroadcast()發送有序廣播時它只發給優先級最高的那個,然后由優先級高的接收者傳到優先級低的那里,并且優先級高的接收者有能力中斷廣播,廣播被中斷后優先級低的廣播將收不到廣播。 修改清單文件增加android:priority屬性 ~~~ <receiver android:name =".broadcastreceiver.FirstBroadcastReceiver" > <intent-filter android:priority ="10" > <action android:name ="com.example.BroadcastReceiver" /> <category android:name ="android.intent.category.DEFAULT" /> </intent-filter> </receiver> <receiver android:name =".broadcastreceiver.SecondBroadcastReceiver" > <intent-filter android:priority ="9" > <action android:name ="com.example.BroadcastReceiver" /> <category android:name ="android.intent.category.DEFAULT" /> </intent-filter> </receiver> <receiver android:name =".broadcastreceiver.ThirdBroadcastReceiver" > <intent-filter android:priority ="8" > <action android:name ="com.example.BroadcastReceiver" /> <category android:name ="android.intent.category.DEFAULT" /> </intent-filter> </receiver> ~~~ 在上面一中的2提到當優先級高的廣播收到廣播后一般做兩種處理:(1)是把廣播中斷。(2)接收廣播中的數據并按照需求對此數據做更改首先我們來測一下中斷廣播,我們修改MainActivity的發送廣播的方式 ~~~ //發送一條廣播com.example.BroadcastReceiver要和廣播接收者在清單文件中配置的相同 Intent intent =new Intent("com.example.BroadcastReceiver" ); intent.putExtra("key", "MainActivity中發了一條廣播" ); sendOrderedBroadcast(intent,null); ~~~ 注意,使用sendOrderedBroadcast方法發送有序廣播時,需要一個權限參數,如果為null則表示不要求接收者聲明指定的權限,如果不為null,則表示接收者若要接收此廣播,需聲明指定權限。這樣做是從安全角度考慮的,例如系統的短信就是有序廣播的形式,一個應用可能是具有攔截垃圾短信的功能,當短信到來時它可以先接受到短信廣播,必要時終止廣播傳遞,這樣的軟件就必須聲明接收短信的權限。 所以我們在AndroidMainfest.xml中定義一個權限: ~~~ <permission android:protectionLevel="normal" android:name="com.tsingda.broadcast_permission"/> ~~~ 然后添加此權限 ~~~ <uses-permission android:name="com.tsingda.broadcast_permission" /> ~~~ 然后在SecondBroadcastReceiver?中調用 ~~~ abortBroadcast(); ~~~ 這個方法然后點擊發送按鈕打印日志如下 ![](https://box.kancloud.cn/2016-03-01_56d500e1c4d9b.jpg) 發現ThirdBroadcastReceiver沒有接收到廣播,說明中斷廣播成功。 然后再來看更改廣播中的數據,在講解更改之前我們需要了解setResultExtras(Bundle)這個方法,在進行廣播的傳輸時優先接收到Broadcast的接收者可以通過setResultExtras(Bundle)方法將處理結果存入Broadcast中,然后傳給下一個接收者,下一個接收者通過Bundle bundle = new getResultExtras(true)可以獲取上一個接收者存入的數據。 setResultExtras(Bundle)方法的詳細介紹如下圖 ![](https://box.kancloud.cn/2016-03-01_56d500e1d42dd.jpg) 我們把三個接收者做如下更改 ~~~ package com.example.broadcastreceiverpractice.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; public class FirstBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "FirstBroadcastReceiver" ; @Override public void onReceive(Context context, Intent intent) { String getFromBroadcast = intent.getStringExtra("key" ); Log. i( TAG,getFromBroadcast); Bundle bundle = new Bundle(); bundle.putString( "key", getFromBroadcast+ "@First"); setResultExtras(bundle); } } ~~~ ~~~ package com.example.broadcastreceiverpractice.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; public class SecondBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "SecondBroadcastReceiver" ; @Override public void onReceive(Context context, Intent intent) { String getFromBroadcast = getResultExtras(true ).getString("key" ); Log. i( TAG,getFromBroadcast); Bundle bundle = new Bundle(); bundle.putString( "key", getFromBroadcast+ "@Second"); setResultExtras(bundle); } } ~~~ ~~~ package com.example.broadcastreceiverpractice.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class ThirdBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "ThirdBroadcastReceiver" ; @Override public void onReceive(Context context, Intent intent) { String getFromBroadcast = getResultExtras(true ).getString("key" ); Log. i( TAG,getFromBroadcast); } } ~~~ 點擊發送廣播按鈕打印日志如下 ![](https://box.kancloud.cn/2016-03-01_56d500e1e684c.jpg) 說明我們接收到了廣播并進行了修改然后傳到了下一級。好了關于廣播接收者的討論就到這了,如果錯誤歡迎批評指正,謝謝
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看