图解 Android 广播机制

来源:互联网 发布:网络高清直播 编辑:程序博客网 时间:2024/04/29 02:10

从现实生活中理解广播机制

一听到广播我们第一感觉就会联想到小时候村里面的广播,每逢村里有什么活动都是通过广播发送的。收听收音机也是一种广播,在收音机中有很多个广播电台,每个广播电台播放的内容都不相同。接受广播时广播(发送方)并不在意我们(接收方)接收到广播时如何处理。好比我们收听交通电台的广播,电台中告诉我们现在在交通状况如何,但它并不关心我们接收到广播时做如何做出处理,这不是广播应该关心的问题,OK,到这里我们从生活中的一些小例子浅浅的理解了一下广播,那么Android 中的广播是如何操作的呢?

Android 的广播机制

在 Android 里面有各种各样的广播,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。下面我画一张粗略的图来帮助大家理解广播的运行机制。

Android 中有各式各样的广播,各种广播在Android 系统中运行,当系统/应用程序运行时便会向 Android 注册各种广播,Android 接收到广播会便会判断哪种广播需要哪种事件,然后向不同需要事件的应用程序注册事件,不同的广播可能处理不同的事件也可能处理相同的广播事件,这时就需要Android 系统为我们做筛选。

案例分析:

一个经典的电话黑名单,首先通过将黑名单号码保存在数据库里面,当来电时,我们接收到来电广播并将黑名单号码与数据库中的某个数据做匹配,如果匹配的话则做出相应的处理,比如挂掉电话、比如静音等等。。。

 

Demo 分析:

下面通过一个小DEMO 来讲解一下广播在Android 中如何编写,在Demo中我们设置了一个按钮为按钮设置点击监听通过点击发送广播,在后台中接收到广播并打印LOG信息。代码如下:

 

复制代码
BroadCastActivity 页面代码
public class BroadCastActivity extends Activity {
    
public static final String ACTION_INTENT_TEST = "com.terry.broadcast.test";

    
/** Called when the activity is first created. */
    @Override
    
public void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button btn 
= (Button) findViewById(R.id.Button01);
        btn.setOnClickListener(
new OnClickListener() {

            @Override
            
public void onClick(View v) {
                
// TODO Auto-generated method stub
                Intent intent = new Intent(ACTION_INTENT_TEST);
                sendBroadcast(intent);
            }
        });
    }
}
复制代码

 

 

接收器代码如下:

 

复制代码
public class myBroadCast extends BroadcastReceiver {

     
    
public myBroadCast() {
        Log.v(
"BROADCAST_TAG""myBroadCast");
    }

    @Override
    
public void onReceive(Context context, Intent intent) {
        
// TODO Auto-generated method stub
        Log.v("BROADCAST_TAG""onReceive");
    }

}
复制代码

 

Android 广播的生命周期

在上面的接收器中,继承了BroadcastReceiver 并重写了它的onReceive 并构造了一个函数,下面通过图片来一步一步认识 Android 广播的生命周期。当我点击一下按钮,它向Android 发送了一个广播,如下图:

这时我们再点击一下按钮,它还是会再向 Android 系统发送广播,此时日志信息如下:

下面本人画一张图像,描述了Android 中广播的生命周期,其次它并不像Activity 一样复杂,运行原理很简单如下图:

下面来看一下SDK给出的解释:

大意为:如果一个广播处理完onReceive 那么系统将认定此对象将不再是一个活动的对象,也就会finished掉它。

至此,大家应该能明白 Android 的广播生命周期的原理,代码也不用多介绍,很简单的一个发送广播并处理广播的Demo。

 

Android 如何判断并筛选广播?

前面说过 Android 的广播有各式各样,那么Android 系统是如何帮我们处理我们需要哪种广播并为我们提供相应的广播服务呢?这里有一点需要大家注意,每实现一个广播接收类必须在我们应用程序中的 manifest 中显式的注明哪一个类需要广播,并为其设置过滤器,如下图:

Tip:action 代表一个要执行的动作,在Andriod 中有很action 比如 ACTION_VIEW,ACTION_EDIT


那么有些人会问了,如果我在一个广播接收器中要处理多个动作呢?那要如何去处理?
在Android 的接收器中onReceive 以经为我们想到的,同样的你必须在Intent-filter 里面注册该动作,可以是系统的广播动作也可以是自己需要的广播,之后你之需要在onReceive 方法中,通过intent.getAction()判断传进来的动作即可做出不同的处理,不同的动作。具体大家可以去尝试测试一下。



小结:
  • 在Android 中如果要发送一个广播必须使用sendBroadCast 向系统发送对其感兴趣的广播接收器中。
  • 使用广播必须要有一个intent 对象必设置其action动作对象
  • 使用广播必须在配置文件中显式的指明该广播对象
  • 每次接收广播都会重新生成一个接收广播的对象
  • 在BroadCast 中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity 或者 Service 去处理



:android广播的使用

在Activity中,注册广播的一个Demo。

总共分3步

第一步:定义一个BroadcastReceiver广播接收类:

view plain

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){ 

        @Override 

        public void onReceive(Context context, Intent intent) { 

            String action = intent.getAction(); 

            if(action.equals(ACTION_NAME)){ 

                Toast.makeText(Test.this, "处理action名字相对应的广播", 200); 

            } 

        } 

         

    }; 

 

第二步:注册该广播:

view plain

public void registerBoradcastReceiver(){ 

        IntentFilter myIntentFilter = new IntentFilter(); 

        myIntentFilter.addAction(ACTION_NAME); 

        //注册广播       

        registerReceiver(mBroadcastReceiver, myIntentFilter); 

    } 

 

第三步:触发响应

 

view plain

mBtnMsgEvent = new Button(this); 

        mBtnMsgEvent.setText("发送广播"); 

        mBtnMsgEvent.setOnClickListener(new OnClickListener() { 

            @Override 

            public void onClick(View v) { 

                Intent mIntent = new Intent(ACTION_NAME); 

                mIntent.putExtra("yaner", "发送广播,相当于在这里传送数据"); 

                 

                //发送广播 

                sendBroadcast(mIntent); 

            } 

        }); 

     

 

 

-----最后附上完整代码:

view plain

package my.yaner; 

 

import android.app.Activity; 

import android.content.BroadcastReceiver; 

import android.content.Context; 

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; 

import android.widget.LinearLayout; 

import android.widget.Toast; 

 

public class Test extends Activity{ 

    private final String ACTION_NAME = "发送广播"; 

    private Button mBtnMsgEvent = null; 

     

    protected void onCreate(Bundle savedInstanceState){ 

        super.onCreate(savedInstanceState); 

         

        //注册广播 

        registerBoradcastReceiver(); 

         

        LinearLayout mLinearLayout = new LinearLayout(this); 

        mBtnMsgEvent = new Button(this); 

        mBtnMsgEvent.setText("发送广播"); 

        mLinearLayout.addView(mBtnMsgEvent); 

        setContentView(mLinearLayout); 

         

        mBtnMsgEvent.setOnClickListener(new OnClickListener() { 

            @Override 

            public void onClick(View v) { 

                Intent mIntent = new Intent(ACTION_NAME); 

                mIntent.putExtra("yaner", "发送广播,相当于在这里传送数据"); 

                 

                //发送广播 

                sendBroadcast(mIntent); 

            } 

        }); 

    } 

     

    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){ 

        @Override 

        public void onReceive(Context context, Intent intent) { 

            String action = intent.getAction(); 

            if(action.equals(ACTION_NAME)){ 

                Toast.makeText(Test.this, "处理action名字相对应的广播", 200); 

            } 

        } 

         

    }; 

     

    public void registerBoradcastReceiver(){ 

        IntentFilter myIntentFilter = new IntentFilter(); 

        myIntentFilter.addAction(ACTION_NAME); 

        //注册广播       

        registerReceiver(mBroadcastReceiver, myIntentFilter); 

    } 


:Android广播机制(两种注册方法)与中断广播

两种注册类型的区别是:

     1)第一种不是常驻型广播,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。

     2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

在android下,要想接受广播信息,那么这个广播接收器就得我们自己来实现了,我们可以继承BroadcastReceiver,就可以有一个广播接受器了。有个接受器还不够,我们还得重写BroadcastReceiver里面的onReceiver方法,当来广播的时候我们要干什么,这就要我们自己来实现,不过我们可以搞一个信息防火墙。具体的代码:

public class SmsBroadCastReceiver extends BroadcastReceiver   
{  
 
    @Override 
    public void onReceive(Context context, Intent intent)  
    {  
        Bundle bundle = intent.getExtras();  
        Object[] object = (Object[])bundle.get("pdus");  
        SmsMessage sms[]=new SmsMessage[object.length];  
        for(int i=0;i<object.length;i++)  
        {  
            sms[0] = SmsMessage.createFromPdu((byte[])object[i]);  
            Toast.makeText(context, "来自"+sms[i].getDisplayOriginatingAddress()+" 的消息是:"+sms[i].getDisplayMessageBody(), Toast.LENGTH_SHORT).show();  
        }  
        //终止广播,在这里我们可以稍微处理,根据用户输入的号码可以实现短信防火墙。  
        abortBroadcast();  
    }  
      
 
  当实现了广播接收器,还要设置广播接收器接收广播信息的类型,这里是信息:android.provider.Telephony.SMS_RECEIVED
  我们就可以把广播接收器注册到系统里面,可以让系统知道我们有个广播接收器。这里有两种,一种是代码动态注册:

//生成广播处理  
smsBroadCastReceiver = new SmsBroadCastReceiver();  
//实例化过滤器并设置要过滤的广播  
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//注册广播
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver, intentFilter); 

 

一种是在AndroidManifest.xml中配置广播

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      package="spl.broadCastReceiver" 
      android:versionCode="1" 
      android:versionName="1.0"> 
    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
        <activity android:name=".BroadCastReceiverActivity" 
                  android:label="@string/app_name"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
          
        <!--广播注册--> 
        <receiver android:name=".SmsBroadCastReceiver"> 
            <intent-filter android:priority="20"> 
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/> 
            </intent-filter> 
        </receiver> 
          
    </application> 
      
    <uses-sdk android:minSdkVersion="7" /> 
      
    <!-- 权限申请 --> 
    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> 
      
</manifest>



原创粉丝点击