zoukankan      html  css  js  c++  java
  • Android学习笔记--Broadcast, BroadcastReceiver(广播)

    参考资料:http://www.cnblogs.com/playing/archive/2011/03/23/1992030.html

    在 Android 中使用 Activity, Service, Broadcast, BroadcastReceiver

    活动(Activity) - 用于表现功能
    服务(Service) - 相当于后台运行的 Activity
    广播(Broadcast) - 用于发送广播
    广播接收器(BroadcastReceiver) - 用于接收广播

    Intent - 用于连接以上各个组件,并在其间传递消息

    ==========================================================================

    BroadcastReceiver:

    在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件。下面将详细的阐述如何发送Broadcast和使用BroadcastReceiver过滤接收的过程:

    首先在需要发送信息的地方,把要发送的信息和用于过滤的信息(如Action、Category)装入一个Intent对象,然后通过调用 Context.sendBroadcast()、sendOrderBroadcast()或sendStickyBroadcast()方法,把 Intent对象以广播方式发送出去。

    当Intent发送以后,所有已经注册的BroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent相匹配,若匹配则就会调用BroadcastReceiver的onReceive()方法。所以当我们定义一个BroadcastReceiver的时候,都需要实现onReceive()方法。

    注册BroadcastReceiver有两种方式:

    一种方式是,静态的在AndroidManifest.xml中用<receiver>标签生命注册,并在标签内用<intent- filter>标签设置过滤器。

    另一种方式是,动态的在代码中先定义并设置好一个 IntentFilter 对象,然后在需要注册的地方调Context.registerReceiver()方法,如果取消时就调用 Context.unregisterReceiver()方法。如果用动态方式注册的BroadcastReceiver的Context对象被销毁时,BroadcastReceiver也就自动取消注册了。(特别注意,有些可能需要后台监听的,如短信消息)

    另外,若在使用sendBroadcast()的方法是指定了接收权限,则只有在AndroidManifest.xml中用<uses- permission>标签声明了拥有此权限的BroascastReceiver才会有可能接收到发送来的Broadcast。同样,若在注册BroadcastReceiver时指定了可接收的Broadcast的权限,则只有在包内的AndroidManifest.xml中 用<uses-permission>标签声明了,拥有此权限的Context对象所发送的Broadcast才能被这个 BroadcastReceiver所接收。


    1.静态注册BroadcastReceiver:

    静态注册比动态注册麻烦点,先新建一个类继承BroadcastReceiver,如:

    clsReceiver2.java

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.widget.Toast;
     
    /*
     * 接收静态注册广播的BroadcastReceiver,
     * step1:要到AndroidManifest.xml这里注册消息
     *         <receiver android:name="clsReceiver2">
                <intent-filter>
                    <action
                        android:name="com.testBroadcastReceiver.Internal_2"/>
                </intent-filter>
            </receiver>
        step2:定义消息的字符串
        step3:通过Intent传递消息来驱使BroadcastReceiver触发
     */
    public class clsReceiver2 extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Toast.makeText(context, "静态:"+action, 1000).show();
     
        }
    }

    然后到AndroidManifest.xml 添加receive标签

    <receiver android:name="clsReceiver2">  
        <intent-filter>  
            <action  
                android:name="com.testBroadcastReceiver.Internal_2"/>  
        </intent-filter>  
    </receiver> 

    第一个name是类名,即你的继承BroadcastReceiver的类的名字,里面实现了BroadcastReceive的onReceive()方法,来处理你接到消息的动作。

    第二个name是action的名称,即你要监听的消息名字(其它消息都会被过滤不监听)。


    2.动态注册BroadcastReceiver:

    下面的例子实现了实时显示手机剩余电量
    主要代码部分为:

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.widget.TextView;
    
    public class MainActivity extends ActionBarActivity {
        private TextView textview;
        private BroadcastReceiver batteryChangedReceiver = new BroadcastReceiver(){
            @Override
            public void onReceive(Context context, Intent intent) {
                //判断接收到的是否是电量变化的Broadcast Action
                if(Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())){
                    //level表示当前电量的值
                    int level = intent.getIntExtra("level", 0);
                    //scale表示电量的总刻度
                    int scale = intent.getIntExtra("scale", 100);
                    //电量剩余换算成百分比
                    textview.setText("当前电量剩余:"+(level*100/scale)+"%");                
                }            
            }    
        };
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textview = (TextView)findViewById(R.id.butleft);
            
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //为BroadcastReceiver指定action,即要监听的消息名字。
            //也可以将上两行合并为 IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
            registerReceiver(batteryChangedReceiver,intentFilter); //注册监听
            //另外还有unregisterReceiver(batteryChangedReceiver); //取消监听
            //一般在onStart中注册,onStop中取消unregisterReceiver        
        }   
    }

    ========================================================================

    Broadcast:

    发送广播消息,把要发送的信息和用于过滤的信息(如Action、Category)装入一个Intent对象,然后通过调用 Context.sendBroadcast()、sendOrderBroadcast()或sendStickyBroadcast()方法,把 Intent对象以广播方式发送出去。

    例如:

    Intent intent =new Intent(INTENAL_ACTION_3);
    intent.putExtra("Name", "hellogv");
    intent.putExtra("Blog", "http://blog.csdn.net/hellogv");
    sendBroadcast(intent);//传递过去

    注意:

    1. 广播生命周期只有十秒左右,如果在 onReceive() 内做超过十秒内的事情,就会报ANR(Application No Response) 程序无响应的错误信息,如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由Service 来完成 . 这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的

    2. 动态注册广播接收器还有一个特点,就是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用(但我在两台手机中测试都并非这样。。。。)

  • 相关阅读:
    uva 10370
    uva 10107
    uva 10038
    uva 488
    伪代码格式
    公众号的秘密,知道一个biz就够了
    ToolTip 概述
    swt
    Java GUI图形界面开发工具
    Java多线程-两个小球
  • 原文地址:https://www.cnblogs.com/gnivor/p/4947802.html
Copyright © 2011-2022 走看看