广播接收器

标准广播时一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻收到这条广播消息,因此他们之间没有任何先后顺序可言。这种广播效率会比较高,但同时意味着它是无法被截断的。

有序广播则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。

需要注意的是,不要在onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的,当onReceive()方法运行了较长时间而没有结束时,程序就会报错。

广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。

广播是一种可以跨进程的通信方式

实例

public class MainActivity extends Activity{

    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter =new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//想要监视什么广,就在这里添加相应的action就行了。
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver,intentFilter);
    }

    protected void onDestroy(){
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }

    class NetworkChangeReceiver extends BroadcasrReceiver{

        public void onReceive(Context context,Intent intent){
            ConnectivityManager connectionManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo netWorkInfo =connectionManager.getActiveNetworkInfo();

            if(netWorkInfo!=null&&neWorkInfo.isAvailable()){
                Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show();
            }
        }
    }
}

发送自定义广播

//定义一个接收器
public class MyBroadcastReceiver extends BroadcastReceiver{
    public void onReceive(Context context,Intent intent){
        Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
    }
}


<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
    </intent-filter>
</receiver>

//  发送一个标准广播
publi{c class MainActivity extends Activity{
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener(){
            public void onClick(View view){
                Intent intent=new Intent("com.example.broadcasttest",Toast.LENGTH_SHORT).show();
                sendBroadcast(intent);  //发送广播
            }
        });
    }
} 

//发送有序广播   
public class MainActivity extends Activity{
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener(){
            public void onClick(View view){
                    Intent intent=new Intent("com.example.broadcasttest.MY_BROADCAST");
                    sendOrderBroadcast(intent,null); //发送有序广播  
            }
        });
    }
}

设置优先级:
<receiver android:name=".MyBroadcastReceiver">
    <intent-filter android:priority="100">
        <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
    </intent-filter>
</receiver>

本地广播机制

为了能够简单地解决广播的安全性问题,Android引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。

本地广播的用法并不复杂,主要就是使用了一个LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法。

优点:
1.可以明确地知道正在发送的广播不会离开我们的程序,因此不需要担心机密数据泄露的问题
2.其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患。
3.发送本地广播比起发送系统全局广播将会更加高效。

public class MainActivity extends Activity{

    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBoradcastManager localBroadcastManager;

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        //获取实例
        Button button =(Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener(){
            Intent intent =new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
            localBroadcastManager.sendBroadcast(intent); //发送本地广播
            }
        });
        intentFilter=new IntentFilter();
        intentFilter .addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver =new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);//注册本地广播监听器
    }
    protected void onDestroy(){
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
    class LocalReceiver extends BroadcastReceiver{
        public void onReceive(Context context,Intent intent){
            Toast.makeText(context,"received local broadcast",Toast.LENGTH_SHORT).show();
        }   
    }
}

实例:强制下线

public class ForceOfflineReceiver extends BroadcastReceiver{
    public void onReceive(final Context context,Intent intent){
        AlertDialog.Builder dialogBuilder=new AlertDialog.Builder(context);
        dialogBuilder.setTitle("Warning");
        dialogBuilder.setMessage("You are forced to be offline.Please try to login again.");
        dialogBuilder.setCancelable(false);//设置不可取消
        dialogBuilder.setPositiveButton("OK",new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog,int which){
                ActivityCollector.finishAll(); //销毁所有活动
                Intent intent =new Intent(context,LoginActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);  //重新启动LoginActivity
            }
        });
        AlertDialog alertDialog =dialogBuilder.create();  //需要设置AlertDialog的类型,保证在广播接收器中可以正常弹出
        alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        alertDialog.show();
    }
}
注:
调用setCancelable()方法将对话框设为不可取消。由于我们是在广播接收器里启动活动的,因此一定要给Intent加入FLAG_ACTIVITY_NEW_TASK这个标志。最后,还需要把对话框的类型设为TYPE_SYSTEM_ALERT,不然它将无法在广播接收器里弹出。

由于我们在ForceOfflineReceiver里弹出了一个系统级别的对话框,因此必须要声明android.permission.SYSTEM_ALERT_WINDOW权限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值