欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入Android中BroadcastReceiver的兩種注冊(cè)方式(靜態(tài)和動(dòng)態(tài))詳解

 更新時(shí)間:2016年12月13日 08:34:32   作者:潘侯爺  
這篇文章主要介紹了深入Android中BroadcastReceiver的兩種注冊(cè)方式(靜態(tài)和動(dòng)態(tài))詳解,具有一定的參考價(jià)值,有需要的可以了解一下。

今天我們一起來(lái)探討下安卓中BroadcastReceiver組件以及詳細(xì)分析下它的兩種注冊(cè)方式。

BroadcastReceiver也就是“廣播接收者”的意思,顧名思義,它就是用來(lái)接收來(lái)自系統(tǒng)和應(yīng)用中的廣播。在Android系統(tǒng)中,廣播體現(xiàn)在方方面面,例如當(dāng)開(kāi)機(jī)完成后系統(tǒng)會(huì)產(chǎn)生一條廣播,接收到這條廣播就能實(shí)現(xiàn)開(kāi)機(jī)啟動(dòng)服務(wù)的功能;當(dāng)網(wǎng)絡(luò)狀態(tài)改變時(shí)系統(tǒng)會(huì)產(chǎn)生一條廣播,接收到這條廣播就能及時(shí)地做出提示和保存數(shù)據(jù)等操作;當(dāng)電池電量改變時(shí),系統(tǒng)會(huì)產(chǎn)生一條廣播,接收到這條廣播就能在電量低時(shí)告知用戶及時(shí)保存進(jìn)度等等。Android中的廣播機(jī)制設(shè)計(jì)的非常出色,很多事情原本需要開(kāi)發(fā)者親自操作的,現(xiàn)在只需等待廣播告知自己就可以了,大大減少了開(kāi)發(fā)的工作量和開(kāi)發(fā)周期。而作為應(yīng)用開(kāi)發(fā)者,就需要數(shù)練掌握Android系統(tǒng)提供的一個(gè)開(kāi)發(fā)利器,那就是BroadcastReceiver。

在我們?cè)敿?xì)分析創(chuàng)建BroadcastReceiver的兩種注冊(cè)方式前,我們先羅列本次分析的大綱:

(1)對(duì)靜態(tài)和動(dòng)態(tài)兩種注冊(cè)方式進(jìn)行概念闡述以及演示實(shí)現(xiàn)步驟

(2)簡(jiǎn)述兩種BroadcastReceiver的類(lèi)型(為后續(xù)注冊(cè)方式的對(duì)比做準(zhǔn)備)

(3)在默認(rèn)廣播類(lèi)型下設(shè)置優(yōu)先級(jí)和無(wú)優(yōu)先級(jí)情況下兩種注冊(cè)方式的比較

(4)在有序廣播類(lèi)型下兩種注冊(cè)方式的比較

(5)通過(guò)接受打電話的廣播,在程序(Activity)運(yùn)行時(shí)和終止運(yùn)行時(shí),對(duì)兩種注冊(cè)方式的比較

(6)總結(jié)兩種方式的特點(diǎn)

第一步:靜態(tài)和動(dòng)態(tài)注冊(cè)方式基本概念以及實(shí)現(xiàn)步驟

構(gòu)建Intent,使用sendBroadcast方法發(fā)出廣播定義一個(gè)廣播接收器,該廣播接收器繼承BroadcastReceiver,并且覆蓋onReceive()方法來(lái)響應(yīng)事件注冊(cè)該廣播接收器,我們可以在代碼中注冊(cè)(動(dòng)態(tài)注冊(cè)),也可以AndroidManifest.xml配置文件中注冊(cè)(靜態(tài)注冊(cè))。

動(dòng)態(tài)注冊(cè):

效果如下圖:

這里就不演示點(diǎn)擊按鈕布局的實(shí)現(xiàn)了,MainActivity.java中實(shí)現(xiàn)代碼如下:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
  DynamicReceiver dynamicReceiver;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //實(shí)例化IntentFilter對(duì)象
    IntentFilter filter = new IntentFilter();
    filter.addAction("panhouye");
    dynamicReceiver = new DynamicReceiver();
    //注冊(cè)廣播接收
    registerReceiver(dynamicReceiver,filter);
  }
  //按鈕點(diǎn)擊事件
  public void send2(View v){
    Intent intent = new Intent();
    intent.setAction("panhouye");
    intent.putExtra("sele","潘侯爺");
    sendBroadcast(intent);
  }
  /*動(dòng)態(tài)注冊(cè)需在Acticity生命周期onPause通過(guò)
   *unregisterReceiver()方法移除廣播接收器,
   * 優(yōu)化內(nèi)存空間,避免內(nèi)存溢出
   */
  @Override
  protected void onPause() {
    super.onPause();
    unregisterReceiver(new MyReceiver());
  }
  //通過(guò)繼承 BroadcastReceiver建立動(dòng)態(tài)廣播接收器
  class DynamicReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
      //通過(guò)土司驗(yàn)證接收到廣播
      Toast t = Toast.makeText(context,"動(dòng)態(tài)廣播:"+ intent.getStringExtra("sele"), Toast.LENGTH_SHORT);
      t.setGravity(Gravity.TOP,0,0);//方便錄屏,將土司設(shè)置在屏幕頂端
      t.show();
    }
  }
}

建立方法代碼中做了詳細(xì)注釋?zhuān)胁幻靼椎牡胤秸?qǐng)留言討論。

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

效果如下:

靜態(tài)注冊(cè)建立第一步,新建BroadcastReceiver,見(jiàn)下圖:

通過(guò)以上步驟,生成MyReceiver.java文件:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.view.Gravity;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
  public MyReceiver() {
  }
  @Override
  public void onReceive(Context context, Intent intent) {
    Toast t = Toast.makeText(context,"靜態(tài)廣播:"+intent.getStringExtra("info"), Toast.LENGTH_SHORT);
    t.setGravity(Gravity.TOP,0,0);
    t.show();
  }
}

生成MyReceiver.java的同時(shí),修改AndroidMainfest.xml配置文件中的代碼:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.administrator.day19">
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
  <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    //生成的receiver配置文件
    <receiver
      android:name=".MyReceiver"
      android:enabled="true"
      android:exported="true">
      <intent-filter>
      //自定義Action
        <action android:name="MLY" />
      </intent-filter>
    </receiver>
  </application>
</manifest>

最后在MainActivity.java文件中添加按鈕點(diǎn)擊事件,如下:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
  DynamicReceiver dynamicReceiver;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
  //靜態(tài)廣播點(diǎn)擊
  public void send(View v){
    Intent intent = new Intent();
    intent.setAction("MLY");
    intent.putExtra("info","panhouye");
    sendBroadcast(intent);
  }
}

至此,兩種注冊(cè)方式的實(shí)現(xiàn)代碼演示完畢,歡迎探討。

第二步:為方便后續(xù)分析,這里插入BroadcastReceiver的兩種常用類(lèi)型

(1)Normalbroadcasts:默認(rèn)廣播

發(fā)送一個(gè)默認(rèn)廣播使用Context.sendBroadcast()方法,普通廣播對(duì)于多個(gè)接收者來(lái)說(shuō)是完全異步的,通常每個(gè)接收者都無(wú)需等待即可以接收到廣播,接收者相互之間不會(huì)有影響。對(duì)于這種廣播,接收者無(wú)法終止廣播,即無(wú)法阻止其他接收者的接收動(dòng)作。

(2)orderedbroadcasts:有序廣播

發(fā)送一個(gè)有序廣播使用Context.sendorderedBroadcast()方法,有序廣播比較特殊,它每次只發(fā)送到優(yōu)先級(jí)較高的接收者那里,然后由優(yōu)先級(jí)高的接受者再傳播到優(yōu)先級(jí)低的接收者那里,優(yōu)先級(jí)高的接收者有能力終止這個(gè)廣播。

發(fā)送有序廣播:sendorderedBroadCast()

在注冊(cè)廣播中的<intent-filter>中使用android:priority屬性。這個(gè)屬性的范圍在-1000到1000,數(shù)值越大,優(yōu)先級(jí)越高。在廣播接收器中使用setResultExtras方法將一個(gè)Bundle對(duì)象設(shè)置為結(jié)果集對(duì)象,傳遞到下一個(gè)接收者那里,這樣優(yōu)先級(jí)低的接收者可以用getResuttExtras獲取到最新的經(jīng)過(guò)處理的信息集合。使用sendorderedBroadcast方法發(fā)送有序廣播時(shí),需要一個(gè)權(quán)限參數(shù),如果為null則表示不要求接收者聲明指定的權(quán)限,如果不為null則表示接收者若要接收此廣播,需聲明指定權(quán)限。這樣做是從安全角度考慮的,例如系統(tǒng)的短信就是有序廣播的形式,一個(gè)應(yīng)用可能是具有攔截垃圾短信的功能,當(dāng)短信到來(lái)時(shí)它可以先接受到短信廣播,必要時(shí)終止廣播傳遞,這樣的軟件就必須聲明接收短信的權(quán)限。

第三步:在默認(rèn)廣播下兩種注冊(cè)方式的比較

(1)兩種注冊(cè)方式均不設(shè)置優(yōu)先級(jí)

這里將動(dòng)態(tài)與靜態(tài)兩種注冊(cè)的廣播觸發(fā)集中在一個(gè)按鈕上,顯示效果如下(未設(shè)置優(yōu)先級(jí)的情況下,先動(dòng)態(tài)后靜態(tài)):

這里同樣不演示按鈕布局文件,以及靜態(tài)注冊(cè)涉及AndroidMainfest.xml和MyReceiver.java文件。直接展示MainActicity.java的實(shí)現(xiàn)代碼:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
  DynamicReceiver dynamicReceiver;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    IntentFilter filter = new IntentFilter();
    filter.addAction("panhouye");
    dynamicReceiver = new DynamicReceiver();
    registerReceiver(dynamicReceiver,filter);
  }
  //靜態(tài)廣播點(diǎn)擊
  public void send(View v){
    Intent intent = new Intent();
    //設(shè)置與動(dòng)態(tài)相同的Action,方便同時(shí)觸發(fā)靜態(tài)與動(dòng)態(tài)
    intent.setAction("panhouye");
    intent.putExtra("info","潘侯爺");
    sendBroadcast(intent);//默認(rèn)廣播
  }
  @Override
  protected void onPause() {
    super.onPause();
    unregisterReceiver(new MyReceiver());
  }
  class DynamicReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
      Toast t = Toast.makeText(context,"動(dòng)態(tài)廣播:"+ intent.getStringExtra("info"), Toast.LENGTH_SHORT);
      t.setGravity(Gravity.TOP,0,0);
      t.show();
    }
  }
}

(2)將動(dòng)態(tài)優(yōu)先級(jí)設(shè)置為最低-1000,靜態(tài)優(yōu)先級(jí)設(shè)置為最高1000

顯示效果如下(動(dòng)態(tài)仍先于靜態(tài)被接收到):

MainActivity中動(dòng)態(tài)優(yōu)先級(jí)設(shè)置如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    IntentFilter filter = new IntentFilter();
    filter.addAction("panhouye");
    filter.setPriority(-1000);//設(shè)置動(dòng)態(tài)優(yōu)先級(jí)
    dynamicReceiver = new DynamicReceiver();
    registerReceiver(dynamicReceiver,filter);
  }

AndroidMainfest.xml中靜態(tài)優(yōu)先級(jí)設(shè)置如下:

<receiver
  android:name=".MyReceiver"
  android:enabled="true"
  android:exported="true">
  //設(shè)置靜態(tài)優(yōu)先級(jí)
  <intent-filter android:priority="1000">
     <action android:name="panhouye" />
  </intent-filter>
</receiver>

第四步:在有序廣播下兩種注冊(cè)方式比較

靜態(tài)廣播1(優(yōu)先級(jí)為200),靜態(tài)廣播2(優(yōu)先級(jí)為300),靜態(tài)廣播3(優(yōu)先級(jí)為400),靜態(tài)廣播優(yōu)先級(jí)為(-100),動(dòng)態(tài)廣播優(yōu)先級(jí)為0。顯示效果如下:

出現(xiàn)順序由優(yōu)先級(jí)決定,由高到低分別為靜態(tài)3-靜態(tài)2-靜態(tài)1-動(dòng)-靜態(tài)。(這里參照前文代碼)

第五步:接受打電話的廣播,比較程序運(yùn)行中與結(jié)束運(yùn)行時(shí),兩種注冊(cè)方式的比較

本次比較采用比對(duì)Log的方式對(duì)兩種注冊(cè)方式進(jìn)行比較,在MainActivity.java中會(huì)插入Activity全部生命周期用于檢測(cè)Log分析。

AndroidMainfest.xml配置文件代碼如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.administrator.test19">
  //添加撥打電話權(quán)限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
  <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <receiver
      android:name=".StaticReceiver"
      android:enabled="true"
      android:exported="true">
      <intent-filter>
        //設(shè)置打電話對(duì)應(yīng)的action
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
      </intent-filter>
    </receiver>
  </application>
</manifest>

MainActivity.java中實(shí)現(xiàn)代碼:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {
  DynamicReceiver dynamicReceiver;//聲明動(dòng)態(tài)注冊(cè)廣播接收
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    IntentFilter filter = new IntentFilter();
    filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
    dynamicReceiver = new DynamicReceiver();
    registerReceiver(dynamicReceiver,filter);
    Log.i("Tag","Activity-onCreate");
  }
  @Override
  protected void onStart() {
    super.onStart();
    Log.i("Tag","Activity-onStart");
  }
  @Override
  protected void onResume() {
    super.onResume();
    Log.i("Tag","Activity-onResume");
  }
  @Override
  protected void onPause() {
    super.onPause();
    Log.i("Tag","Activity-onPause");
  }
  @Override
  protected void onStop() {
    super.onPause();
    Log.i("Tag","Activity-onStop");
  }
  @Override
  protected void onDestroy() {
    super.onDestroy();
    Log.i("Tag","Activity-onDestroy");
    unregisterReceiver(dynamicReceiver);
  }
  class DynamicReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
      Log.i("Tag","動(dòng)態(tài)注冊(cè)廣播接收到您正在撥打電話"+getResultData());
    }
  }
}

StaticReceiver.java中實(shí)現(xiàn)代碼:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class StaticReceiver extends BroadcastReceiver {
  public StaticReceiver() {
  }
  @Override
  public void onReceive(Context context, Intent intent) {
    Log.i("Tag","靜態(tài)注冊(cè)廣播接收到您正在撥打電話"+getResultData());
  }
}

(1)在未退出Activity時(shí),撥打電話,Log如下:

 

由Log可知在未退出Activity是,兩種方式均可接受到廣播。

(2)在退出Activity時(shí),撥打電話,Log如下:

在退出程序(Activity)時(shí),只有靜態(tài)注冊(cè)方式可以接受到廣播。

第六步:總結(jié)兩種注冊(cè)方式特點(diǎn)

廣播接收器注冊(cè)一共有兩種形式:靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè).

兩者及其接收廣播的區(qū)別:

(1)動(dòng)態(tài)注冊(cè)廣播不是常駐型廣播,也就是說(shuō)廣播跟隨Activity的生命周期。注意在Activity結(jié)束前,移除廣播接收器。

靜態(tài)注冊(cè)是常駐型,也就是說(shuō)當(dāng)應(yīng)用程序關(guān)閉后,如果有信息廣播來(lái),程序也會(huì)被系統(tǒng)調(diào)用自動(dòng)運(yùn)行。

(2)當(dāng)廣播為有序廣播時(shí):優(yōu)先級(jí)高的先接收(不分靜態(tài)和動(dòng)態(tài))。同優(yōu)先級(jí)的廣播接收器,動(dòng)態(tài)優(yōu)先于靜態(tài)

(3)同優(yōu)先級(jí)的同類(lèi)廣播接收器,靜態(tài):先掃描的優(yōu)先于后掃描的,動(dòng)態(tài):先注冊(cè)的優(yōu)先于后注冊(cè)的。

(4)當(dāng)廣播為默認(rèn)廣播時(shí):無(wú)視優(yōu)先級(jí),動(dòng)態(tài)廣播接收器優(yōu)先于靜態(tài)廣播接收器。同優(yōu)先級(jí)的同類(lèi)廣播接收器,靜態(tài):先掃描的優(yōu)先于后掃描的,動(dòng)態(tài):先注冊(cè)的優(yōu)先于后冊(cè)的。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論