zoukankan      html  css  js  c++  java
  • Android四大组件之BroadcastReceiver

    什么是BroadcastReceiver?

    BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。

    在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。

    为什么要用BroadcastReceiver?

    Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver。

    BroadcastReceiver的生命周期:

    广播接收器只有一个回调方法:

    void onReceive(Context curContext, Intent broadcastMsg)

    当广播消息抵达接收器时,Android调用它的onReceive() 方法并将包含消息的Intent对象传递给它。广播接收器仅在它执行这个方法时处于活跃状态。当onReceive()返回后,它即为失活状态。

    拥有一个活跃状态的广播接收器的进程被保护起来而不会被杀死。但仅拥有失活状态组件的进程则会在其它进程需要它所占有的内存的时候随时被杀掉。

    这种方式引出了一个问题:如果响应一个广播信息需要很长的一段时间,我们一般会将其纳入一个衍生的线程中去完成,而不是在主线程内完成它,从而保证用户交互过程的流畅。如果onReceive()衍生了一个线程并且返回,则包涵新线程在内的整个进程都被会判为失活状态(除非进程内的其它应用程序组件仍处于活跃状态),于是它就有可能被杀掉。这个问题的解决方法是令onReceive()启动一个新服务,并用其完成任务,于是系统就会知道进程中仍然在处理着工作。

    发送和接收BroadcastReceiver:

    发送广播的方式有两种,一种是同步广播,另一种是异步广播。前者接收器是顺序执行,每执行一个Receiver,待该Receiver返回后再执行下一个,执行的顺序是按照Receiver的优先级,通过清单文件中的Android:priority可以配置Receiver的优先级。异步广播使用sendBroadcast()发送消息,此时接收器会同步执行,彼此独立,系统内部的消息广播采用的就是此种方式。

    sendBroadcast():这种方式不严格保证执行顺序。

    sendOrderBroadcast():这种方式保证执行顺序,根据优先级的高低排序。

    例如:

             Intent intent = new Intent("MessageReceiver");
                    String str=et.getEditableText().toString();
                    intent.putExtra("msg", str);
                    sendBroadcast(intent);

    接收广播需继承BroadcastReceiver,并覆盖其onReceiver方法。例如:

    public class MessageReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String msg = intent.getStringExtra("msg");
            Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    
        }
    
    }

    注册BroadcastReceiver:

    注册BroadcastReceiver有两种方式:

      静态注册:

      在AndroidManifest.xml中用标签生命注册,并在标签内用标签设置过滤器。

      

      <receiver android:name="myRecevice">    //继承BroadcastReceiver,重写onReceiver方法
    
        <intent-filter>    
    
          <action android:name="com.dragon.net"></action> //使用过滤器,接收指定action广播
    
          </intent-filter>
    
      </receiver>

     

      动态注册:

      

      IntentFilter intentFilter = new IntentFilter();
    
      intentFilter.addAction(String);   //为BroadcastReceiver指定action,使之用于接收同action的广播
    
        registerReceiver(BroadcastReceiver,intentFilter);

      一般:在onResume中注册,onPause()中取消unregisterReceiver

    注销BroadcastReceiver:

    // 代码中注销广播

    unregisterReceiver(mBatteryInfoReceiver);

     在 Activity 中代码注销广播建议在: onPuase() 中注销;

    不要这这里面注销 Activity.onSaveInstanceState(), 因为这个方法是保存 Intent 状态的。

    小实例:

     main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10" >
    
            <requestFocus />
        </EditText>
    
        <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送广播" />
    
    </LinearLayout>

    MainActivity.java:

    public class MainActivity extends Activity {
        private EditText et;
    
        // 初始化操作
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            System.out.println("onCreate");
            et = (EditText) findViewById(R.id.et);
            Button btn1 = (Button) findViewById(R.id.btn1);
            btn1.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent("MessageReceiver");
                    String str = et.getEditableText().toString();
                    intent.putExtra("msg", str);
                    sendBroadcast(intent);
    
                }
            });
    
        }
    
    }

    广播接收者:

    public class MessageReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String msg = intent.getStringExtra("msg");
            Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    
        }
    
    }

    清单文件注册:

           <receiver android:name="com.topcsa.test_android.MessageReceiver" >
                <intent-filter>
                    <action android:name="MessageReceiver" />
                </intent-filter>
            </receiver>

    Demo下载:http://download.csdn.net/detail/af74776/7809453(因为我经常用一个工程做很多测试性的小例子,因此代码中会有不需要的代码,请见谅。)

    推荐文章:http://yangguangfu.iteye.com/blog/1063732

         http://www.cnblogs.com/sardine/archive/2010/11/19/1881766.html

         http://www.cnblogs.com/cowboybusy/archive/2012/07/09/2718902.html

  • 相关阅读:
    HashMap 常问的 9 个问题
    P1855 榨取kkksc03
    Codeforces Round #697 (Div. 3) A. Odd Divisor
    P1474 [USACO2.3]Money System / [USACO07OCT]Cow Cash G
    Codeforces Round #704 (Div. 2) D. Genius's Gambit
    P2800 又上锁妖塔
    P2066 机器分配
    P3399 丝绸之路
    P1351 [NOIP2014 提高组] 联合权值
    P4290 [HAOI2008]玩具取名
  • 原文地址:https://www.cnblogs.com/scetopcsa/p/3931852.html
Copyright © 2011-2022 走看看