android第一行代码学习笔记——Broadcast Receiver


  1. android中的广播分为两种:标准广播和有序广播。
  2. 有序广播:一种完全异步执行的广播,在广播发出后,所有的广播接受器几乎都会在同一时刻接收到这条广播消息。执行效率高,无法被截断。
  3. 有序广播:同步执行的广播,广播发出后,同一时刻只会有一个广播接收器能够收到这条广播消息。优先级高的广播接受器先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播。
  4. 接收系统广播:可以使用广播接收器通过监听系统级别的广播来得到各种系统的状态信息。
  5. 广播接收器可以对自己感兴趣的广播进行注册,大部分相应广播发出时,广播接受器能接收到该广播,并在内部处理相应的逻辑。注册广播的方式分为两种:动态注册(在代码中注册)和静态注册(在AndroidMainfest.xml中注册)。
  6. 创建广播接收器(动态注册):新建一个类继承自BroadcastReceiver,并重写父类的onReceive()方法,在该方法内写具体的逻辑。 动态注册的广播接收器一定都要取消注册才行,可以通过调用unregisterReceiver()方法来实现。以下是一个能够监听网络变化的程序。

注意:不要在onReceive()方法中添加过多的逻辑或进行耗时的操作,因为广播接收器中不允许开启线程,当onReceive()方法运行较长时间而没有结束时,程序就会报错。因此广播接受器更多的是用来打开程序其他组件。
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);
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver, intentFilter);
    }

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

    class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectivityManager = (ConnectivityManager)
                    getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isConnected()) {
                Toast.makeText(context, "网络连接正常", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "网络未连接", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

动态注册的广播接收器可以自由地控制注册和注销,在灵活性方便有很大的优势
动态注册的广播接收器必须在程序启动之后才能接收到广播
想要在程序启动之前就能接收到广播可以通过静态注册来实现

7.静态注册:静态注册的广播接受器必须在AndroidManifest.xml文件中注册才可以使用。在application标签中加入receiver标签。

<application
        ...
        <receiver
            android:name=".BootCompleteReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>

8.发送自定义标准广播,代码如下:

Intent intent = new Intent("com.example.yjh.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
---------------------------------------
// android 8.0接受不到自定义广播
// 原因:android 8.0 对静态广播的使用做了一些限制,使用如下方法就可以接收到自定义广播
//修改后的代码如下:
Intent intent = new Intent("com.example.yjh.broadcasttest.MY_BROADCAST");
                // 第一个参数为包名,第二个参数为自定义广播的路径
intent.setComponent(new ComponentName("com.example.yjh.broadcasttest","com.example.yjh.broadcasttest.MyBroadcastReceiver"));
sendOrderedBroadcast(intent, null);

9.可以通过android:priority属性给广播接受器设置优先级,通过优先级来实现有序广播。
10.使用本地广播:为了简单地解决广播的安全性问题,Android引入了一套本地广播机制,该机制使发出的广播只能在程序内部进行传递,并且只能接受本应用程序发出的广播。使用LocalBroadcastManager对广播进行管理,并提供发送广播和注册广播接收器的方法。以下是代码体现:

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private  LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                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);
    }

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

class LocalReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收本地广播", Toast.LENGTH_SHORT).show();
    }
}

猜你喜欢

转载自blog.csdn.net/yjh728/article/details/82468063