美文网首页
Android Broadcast

Android Broadcast

作者: YuQiao0303 | 来源:发表于2019-02-19 14:13 被阅读0次

    标准广播 & 有序广播

    • 标准广播 (Normal broadcasts)
      • 完全异步执行
      • 所有广播接收器几乎都会在同一时刻接收到这条广播消息, 没有任何先后顺序可言
      • 效率较高, 无法被截断
    • 有序广播 (Ordered broadcasts)
      • 同步执行
      • 同一时刻只会有一个广播接收器能够收到这条广播消息
      • 当这个广播接收器中的逻辑执行完毕后, 广播才会继续传递。
      • 所以此时的广播接收器是有先后顺序的, 优先级高的广播接收器就可以
        先收到广播消息,
      • 前面的广播接收器还可以截断正在传递的广播, 这样后面的广播接
        收器就无法收到广播消息了。

    静态注册 & 动态注册

    • 动态注册的广播接收器:
    • 可以自由地控制注册与注销, 灵活
    • 必须要在程序启动之后才能接收到广播, 因为注册的逻辑是写在onCreate() 方法中的。

    注意

    不要在onReceive() 方法中添加过多的逻辑或者进行任何的耗时操作

    因为在广播接收器中是不允许开启线程的, 当onReceive() 方法运行了较长时间而没有结束时, 程序就会报错。

    因此广播接收器更多的是扮演一种打开程序其他组件的角色

    比如创建一条状态栏通知, 或者启动一个服务等, 这几个概念我们会在后面的章节中学到。

    例子:监听网络情况(动态注册,接收系统广播)

    • 写一个activity类内类NetworkChangeReceiver,继承BroadcastReceiver
    • 重写父类的onReceive() 方法就行了。 这样当有广播到来时, onReceive() 方法就会得到执行, 具体的逻辑就可以在这个方法中处理。
    • 在activity的onCreate() 方法中 ,用registerReceiver注册广播接收器
    package com.example.broadcasttest;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
        private IntentFilter intentFilter;
        private NetworkChangeReceiver networkChangeReceiver;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //广播接收器想要监听什么广播, 就在这里add相应的action
            //当网络状态发生变化时, 系统发出的正是一条值为android.net.conn.CONNECTIVITY_CHANGE 的广播
            intentFilter = new IntentFilter();
            intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
            networkChangeReceiver = new NetworkChangeReceiver();
            //下面这一句:NetworkChangeReceiver 就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE 的广播
            registerReceiver(networkChangeReceiver, intentFilter);
        }
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unregisterReceiver(networkChangeReceiver);//动态注册的广播接收器一定都要取消注册才行
        }
    /*---------------------------------BroadcastReceiver的子类----------------------------------------*/
        class NetworkChangeReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                ConnectivityManager connectionManager = (ConnectivityManager)
                        getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
                if (networkInfo != null && networkInfo.isAvailable()) {
                    Toast.makeText(context, "network is available",
                            Toast.LENGTH_SHORT).show();
                }
                else {
                    Toast.makeText(context, "network is unavailable",
                            Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
    

    例子:开机启动(静态注册,接收系统广播)

    1. 用Android Studio提供的快捷方式来创建一个广播接收器
      其中写接收到广播执行的逻辑

    右击com.example.broadcasttest包→New→Other→Broadcast Receiver,

    • Exported 属性:表示是否允许这个广播接收器接收本程序以外的广播,
    • Enabled 属性: 表示是否启用这个广播接收器
    • (静态的广播接收器一定要在AndroidManifest.xml文件中注册才可以使用)
    1. AndroidManifest.xml中:
    • 获取相关权限
    • 给该receiver加上intent-filter 标签,其中标明action(表明接收什么广播)
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.broadcasttest">
    
        <!-- 获取网络状态的权限 -->
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <!-- 获取开机广播 -->
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <receiver
                android:name=".BootCompleteReceiver"
                android:enabled="true"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                </intent-filter>
            </receiver>
            <receiver
                android:name=".MyBroadcastReceiver"
                android:enabled="true"
                android:exported="true"></receiver>
        </application>
    
    </manifest>
    

    发送标准广播

    //发送标准广播
            Button sendButton = (Button) findViewById(R.id.button);
            sendButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                    /**注意:7.0的教程里没有这一句,高版本要加上,否则接收不到广播*/
                    intent.setComponent( new ComponentName( "com.example.broadcasttest" ,
                            "com.example.broadcasttest.MyBroadcastReceiver") );
    
                    sendBroadcast(intent);
                    Log.d(TAG, "onClick: click the button!!");
                }
            });
    

    参考博客:https://blog.csdn.net/haibowen/article/details/80231420

    发送有序广播

    //发送有序广播
            Button sendOrderedButton = (Button) findViewById(R.id.button_order);
            sendOrderedButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                    //7.0的教程里没有这一句,高版本要加上,否则接收不到广播
                    intent.setComponent( new ComponentName( "com.example.broadcasttest" ,
                            "com.example.broadcasttest.MyBroadcastReceiver") );
    
                    sendOrderedBroadcast(intent, null);
                    Log.d(TAG, "onClick: cli ck the button!!");
                }
            });
    

    相关文章

      网友评论

          本文标题:Android Broadcast

          本文链接:https://www.haomeiwen.com/subject/thfeeqtx.html