安卓20_四大组件-BroadcastReceiver
BroadcastReceiver单从字面上解释是广播接受者的意思,那么这里很容易知晓,我们还需要一个广播发送者。这个过程其实和我们日常生活中收听广播一样,发送广播信号的电台会非常多,但是我们只会选择我们感兴趣的选择收听。这里安卓也是一样,并且其实我们的手机时时刻刻都在发送着广播,比如我们电量,由系统随时更新着,而我们大部分的应用都会选择接收它,从而随时知晓电量情况。
广播是一种应用程序之间传输信息的机制。
广播的分类
- 无序广播(普通)
- 有序广播
- 异步广播
广播接收者也需要注册
广播接收者也是四大组件之一,所以它也是需要我们进行注册的,在这里注册的方式有两种。
- 静态注册 mainfest中注册
- 代码注册 java代码中注册
通过案例来简单解释
普通广播(无序)
1.发送一个广播
public class MainActivity extends AppCompatActivity {@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
}public void send(View view){switch (view.getId()){case R.id.btnNormal:Intent normal = new Intent();// 添加一个action 就想电台的电台号一样 以便接收者监听normal.setAction("normal");// 发送一个普通广播sendBroadcast(normal);break;}
}
}
这里是开启了一个普通广播,并且广播的标示是
normal。当然光发送肯定不够我们还需要一个接受者。
2.创建广播接受者
public class NormalReceiver extends BroadcastReceiver {/*** 接收到广播以后的操作* @param context 上下文对象* @param intent 意图对象*/
@Override
public void onReceive(Context context, Intent intent) {String msg = intent.getStringExtra("msg");// 获取其中消息Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
}
}
到这里我们还需要去注册广播
3.广播的注册
静态注册在mainfest当中添加标签
注意其中添加了一个,目的就是过滤筛选,保证接收着能接收的就是我们发送的这个广播。
动态注册
public class MainActivity extends AppCompatActivity {
IntentFilter intentFilter;
NormalReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);intentFilter = new IntentFilter("normal");receiver = new NormalReceiver();registerReceiver(receiver,intentFilter);// 注册
}public void send(View view){switch (view.getId()){case R.id.btnNormal:Intent normal = new Intent();normal.putExtra("msg","普通广播");normal.setAction("normal");sendBroadcast(normal);break;}
}@Override
protected void onDestroy() {super.onDestroy();unregisterReceiver(receiver);// 取消注册
}
}
两者区别:
静态注册存在于mainfest.xml是全局的,当应用启动就会存在,而代码注册是只有当相应组件启动后才会有,比如这里的Activity。而且代码注册的方式,一定不要忘记取消注册。
结果:
执行流程分析
理解普通广播,有序和异步其实就会简单很多了。主要是注册和接收回调前期会比较难理解。后面的我就只写一种注册方式了
有序广播
有序广播,既然是有序也就是以为着我们能够决定接收着接收的顺序。接收的顺序可以通过优先级来设置,这个谷歌官方是要求在-1000-1000,其实你写到int最大取值也没毛病,但是既然是谷歌推荐,咱们照办就好。有序比无序更加灵活,可以截断,可以传递数据等。
1.发送有序广播
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
}public void send(View view) {switch (view.getId()) {case R.id.btnNormal:Intent normal = new Intent();normal.putExtra("msg", "普通广播");normal.setAction("normal");sendBroadcast(normal);break;case R.id.btnOrder:Intent order = new Intent();order.putExtra("msg", "Order");order.setAction("order");sendOrderedBroadcast(order, null);break;}
}@Override
protected void onDestroy() {super.onDestroy();
}
}
和发送普通广播只有调用的方法不一样,调用的是sendOrderedBroadcast
2.接收没有太大变化
public class MyReceiverOne extends BroadcastReceiver {@Override
public void onReceive(Context context, Intent intent) {String msg = intent.getStringExtra("msg");Log.i("receiver","One接收到了消息"+msg);
}
}
3.主要是在注册当中变化明显
这里有两个广播接收者,同时都是接收的为order的广播,需要注意的是在intent-filter中有一个priority属性,两个接收者的属性值是不一样的,Two要比One高,也就意味着Two是先接收到,有就反应出有序了。
结果
当然有序广播还可以进行截断、处理后再传递。比如我这里让Two先接收后处理一些信息后,再传递给One。
Two中代码:
public class MyReceiverTwo extends BroadcastReceiver {@Override
public void onReceive(Context context, Intent intent) {String msg = intent.getStringExtra("msg");Log.i("receiver","Two接收到了消息"+msg);Bundle bundle = new Bundle();bundle.putString("result","Two处理过后的数据");// 设置处理过后的数据setResultExtras(bundle);
}
}
One中代码:
public class MyReceiverOne extends BroadcastReceiver {@Override
public void onReceive(Context context, Intent intent) {String msg = intent.getStringExtra("msg");Log.i("receiver","One接收到了消息"+msg);Bundle bundle = getResultExtras(true);// 获取已经被处理过的数据String data = bundle.getString("result");Log.i("receiver","One:"+data);
}
}
结果:
有序广播和普通广播的比较
异步广播
异步可以先发送后注册
发送
public class MainActivity extends AppCompatActivity {
MyReceiverThree receiver;
IntentFilter filter;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);receiver = new MyReceiverThree();filter = new IntentFilter("sticky");}public void send(View view) {switch (view.getId()) {case R.id.btnNormal:Intent normal = new Intent();normal.putExtra("msg", "普通广播");normal.setAction("normal");sendBroadcast(normal);break;case R.id.btnOrder:Intent order = new Intent();order.putExtra("msg", "Order");order.setAction("order");sendOrderedBroadcast(order, null);break;case R.id.btnSticky:Intent sticky = new Intent();sticky.setAction("sticky");sticky.putExtra("msg","Sticky");sendStickyBroadcast(sticky); // 先发送registerReceiver(receiver,filter);// 后注册break;}
}@Override
protected void onDestroy() {super.onDestroy();unregisterReceiver(receiver);
}
}
接收就没什么好说的了。
重要的是发送异步广播需要在清单文件添加权限: 不然就会出现错误,结果也就不演示了
掌握好广播的发送,数据的传递,并且不要在广播中做耗时操作。