第一行代码读书笔记
广播机制
- 标准广播
- 完全异步执行的广播
- 广播发出后,所有广播接收器几乎在同一时刻接收到这条广播消息,没有先后顺序
- 效率比较高,无法被截断
- 有序广播
- 同步执行的广播
- 同一个时刻只有一个广播接收器能收到消息
这个广播接收器中的逻辑执行完以后才会继续传递,有先后顺序 - 优先级高的广播接收器先收到广播消息
- 前面的广播接收器可以截断正在传递的广播
接收系统广播
- 广播接收器 Broadcast
- 注册广播
- 动态注册:
在代码中注册 - 静态注册:
在AndroidManifest.xml中注册
- 动态注册:
- 创建广播接收器:
继承自Broadcast-receiver并重写父类的onReceive()
动态注册监听网络变化
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeRecevier;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeRecevier = new NetworkChangeReceiver();
registerReceiver(networkChangeRecevier, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeRecevier);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
}
}
}
- 网络状态发生变化时,系统发出一条值为
android.net.conn.CONNECTIVITY_CHANGE的广播 addAction():监听什么广播- registerReceiver()注册广播接收器
- 最后一定要取消注册
- 提示用户有网络还是没网络
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(); } } }ConnectivityManager:系统服务类,专门用于管理网络连接- 如果程序需要进行一些对用户来说比较敏感的操作,必须在配置文件中声明权限才可以
在AndroidManifest.xml中加入:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 缺点:程序启动后才能接收到广播
静态注册实现开机启动
- com.example.broadcasttest包->New->Ohter->Broadcast Receiver
Exported:是否允许这个广播接收器接收本程序意外的广播Enabled:是否启用这个广播接收器
public class BootCompleteReceiver extentds BroadcastReceiver { @Override public void onReceveive(Context context, Intent intent) { Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show(); } }- 静态的广播接收器一定要在AndroidManifest.xml中注册才能使用
- 快捷方式创建的广播接收器自动注册了
<receiver android:name=".BootCompleteReceiver" android:enabled="true" android:exported="true" /receiver> - 添加权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />- (未添加权限报错:Missing permissions required by...)
不要在onReceive()方法中添加过多的逻辑或进行耗时操作
广播接收器中不允许开线程
当onReceive()运行了较长时间没有结束时,程序会报错
广播接收器更多扮演一种打开程序其他组件的角色
发送自定义广播
发送标准广播
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener((new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
}
}));
- 构建Intent对象,并把要发送的广播值传入
- 调用Context的
sendBoradcast()方法将广播发送出去 - 由于广播是使用Intent传递的,可以在Intent中携带一些数据传递给广播接收器
发送有序广播
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener((new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent, null);
}
}));
sendOrderedBroadcast()接收两个参数- 第一个参数:Intent
- 第二个参数:一个与权限相关的字符串
- 设定先后顺序:在
<receiver>标签的<intent-filter>中添加属性
android:priority="100" - 是否允许广播继续传递:在广播接收器的onReceive()中添加
abortBroadcast();
使用本地广播
- 使用该机制发出的广播只能在应用程序的内部传递,
且广播接收器也只能接收来自本应用程序发出的广播 - 使用
LocalBroadcastManager对广播进行管理
并提供了发送广播和注册广播接收器的方法
(在android.support.v4.content包中)
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 = LoacalBroadcastManager.getInstance(this);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener((new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
}));
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.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, "receive local broadcast", Toast.LENGTH_SHORT).show();
}
}
}
- 本地广播无法通过静态注册的方式接收
- 比全局广播更加高效
- 广播不会离开程序:机密数据不会泄露
其他程序无法发送广播进来,不会有安全漏洞的隐患