安卓广播的静态注册和动态注册

今天介绍一下Android的四大组件之一的BroadCastReceiver,即广播。广播类似于JAVA设计模式中的观察者模式,即当被观察者数据变化的时候,会去通知观察者做相应处理。这里也是一样,当发出广播的时候,那么注册过该广播的人,就能收到这个广播,进而做一些工作。

  上面说的广播注册,在Android中有两种方式,即动态注册(代码注册)、静态注册(清单文件注册),下面我以Android中网络状态变化发出的广播作为例子,看看这两种方式的具体用法。

 


动态注册:即用代码动态的注册、注销广播

复制代码
public class DynamicInternetActivity extends AppCompatActivity {

    private InternetDynamicBroadCastReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dynamic_lock_screen);

        IntentFilter filter = new IntentFilter();
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        mReceiver = new InternetDynamicBroadCastReceiver();
        this.registerReceiver(new InternetDynamicBroadCastReceiver(), filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }

    public class InternetDynamicBroadCastReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(DynamicInternetActivity.this,"网络发生了变化",Toast.LENGTH_SHORT).show();
        }
    }
}
复制代码

  在清单文件中注册该广播接受者。

 

  注意:上面在onDestroy方法中,必须注销广播,否则有内存泄漏的风险!!!

 


静态广播:把广播写死在manifest.xml中

public class InternetStaticBroadCastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"网络发生了变化",Toast.LENGTH_SHORT).show();
    }
}

在清单文件中注册该广播接受者。


    
        
        //此处必需指定action,否则监听不到
    

  注意:静态注册的广播,必需单独成一个类,不能像动态注册那样写在某个界面里。否则当监听到网络状态变化的时候,会抛出异常。

 

动态注册和静态注册的区别:

  动态注册的广播会受Activity的生命周期的影响, 当Activity销毁的时候,广播就失效了。

  而静态注册的广播,即使Activity销毁了,仍然可以收到广播。更牛掰的是即使杀死进程,仍然可以收到广播,关于这点不同的手机测试的结果是不同的,为了验证这个问题,我用的是google的nexus手机测试的。

  在Android中,有一些action是不支持静态注册的:

    android.intent.action.SCREEN_ON

    android.intent.action.SCREEN_OFF

    android.intent.action.BATTERY_CHANGED

    android.intent.action.CONFIGURATION_CHANGED

    android.intent.action.TIME_TICK

只能动态注册原因:

有以下几种说法,提供给大家参考:

1.提高系统效率:这两个事件是android的基本事件,如果大多数程序监听,会大大的拖慢整个系统,所以android不鼓励我们在后台监听这两个事件。

2.因为有序广播的优先级问题。以上这些广播中,静态注册时,系统的优先级大于应用,并且系统阻止了广播的向下传播。又因在Android 的广播机制中,动态注册的优先级是要高于静态注册优先级的。故用动态注册代替静态注册。

3.系统安全问题。

解决方式(以android.intent.action.SCREEN_ON为例):

动态注册不能放到activity中,因为动态注册必须要在activity消亡的时候调用unregisterReceiver,会随着activity的解锁消失而不能再接收广播。一般的办法是在activity起来后马上start一个service, 这个service里动态注册一个broadcastreceiver,broadcastreceiver里接收到SCREEN_ON消息后启动锁屏activitty,  为了保证broadcastreceiver任何时候都可以接收到SCREEN_ON,service必须常驻在系统内,所以要接收开机消息android.intent.action.BOOT_COMPLETED。


你可能感兴趣的:(安卓广播的静态注册和动态注册)