广播机制简介:
-----广播接收器(Broadcast Receiver)
1:广播的类型:
1:标准广播 2:有序广播
1:
标准广播(Normal broadcasts)
是一种完全异步执行的广播
,在广播发出之后,所有的 广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可 言。
这种广播的效率会比较高,但同时也意味着它是无法被截断的
。
![](https://i-blog.csdnimg.cn/blog_migrate/2299057a9824deaa6447ec67d6e49cf8.png)
2:
有序广播(Ordered broadcasts)
则是一种同步执行的广播
,在广播发出之后,同一时刻 只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广 播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先 收到广播消息,
并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器 就无法收到广播消息了。
![](https://i-blog.csdnimg.cn/blog_migrate/32a7f646eef2b9bca4b06999ef3b20f4.png)
2:广播的注册方式
一般有两种在代码中注册和在功能清单文件
A
ndroidManifest.xml中注册
也就是
1:动态注册 2:静态注册
1:动态注册
要extends BroadcastReceiver 并重写onReceiver
package com.ys.broadcasttest;
/**
* 自定义广播类 继承 广播接收器
* 使用动态广播注册方式 动态自定义广播(标准广播)
*/
public class MyReceiver extends BroadcastReceiver {
/**
* 重写接收器
* @param context
* @param intent
*/
@Override
public void onReceive(Context context, Intent intent) {
//接收intent消息
String key= intent.getExtras().getString("key");
Toast.makeText(context,"自定义的动态广播开启----\n"+key,Toast.LENGTH_LONG).show();
}
}
1:用意图过滤器(
IntentFilter
)添加"过滤的动作"
2:注册广播
registerReceiver(myReceiver, intentFilter); //注册广播
3:动态注册一定要重写
onDestroy 并取消广播
unregisterReceiver(myReceiver); //取消广播
4:如果是系统自带的广播 如网络变化等,不需要发送广播会自动地监听到并“接收”执行代码
5:不是系统自带地就要发送广播了 就要用意图来发送广播了 这里是动态地配合
意图过滤器
IntentFilter
package com.ys.broadcasttest;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button button;
private MyReceiver myReceiver;
//DYNC_BROADCAST可以随意,但注册广播和发送广播时action应该保持一致
private static final String DYNC_BROADCAST = "com.ys.broadcasttest.MyReceiver";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
button = (Button) findViewById(R.id.button);
broadcastRegister(); //1注册广播
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
sendBroadcastVoid(); //发送广播
break;
}
}
/**
* 注册广播 核心代码
*/
private void broadcastRegister() {
myReceiver = new MyReceiver(); //1 实列化(自定义)广播类
IntentFilter intentFilter = new IntentFilter(); //意图过滤器实例化 用来过滤"动作"
intentFilter.addAction(DYNC_BROADCAST); //添加 广播的动作
registerReceiver(myReceiver, intentFilter); //注册广播
}
/**
* 取消广播 销毁广播 动态广播注册一定要在 重写onDestroy 并取消广播
*/
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver); //取消广播
}
/**
* 发送广播
*/
private void sendBroadcastVoid() {
Intent intent = new Intent();
intent.setAction(DYNC_BROADCAST); //为意图添加广播动作
intent.putExtra("key","广播通过intent可以携带的信息:赖建文---xxx");
sendBroadcast(intent);
}
}
2:静态广播
<
?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ys.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">
<!-- 静态注册广播-->
<receiver
android:name=".staticReceiverDIY"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.ys.broadcasttest.ys2019" />
</intent-filter>
</receiver>
<activity android:name=".Main2Activity" />
<receiver
android:name=".staticSystemReceiver"
android:enabled="true"
android:exported="true">
<!-- 意图过滤器 过滤动作 开机自启的广播动作 BOOT_COMPLETED 引导完成 配合 RECEIVE_BOOT_COMPLETED 权限一起使用 -->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package com.ys.broadcasttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
//静态注册 的自定义广播
public class staticReceiverDIY extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"静态注册 的自定义广播",Toast.LENGTH_LONG).show();
}
}
有序广播也在下面
package com.ys.broadcasttest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button button,button2,button3,button4;
private MyReceiver myReceiver;
//DYNC_BROADCAST可以随意,但注册广播和发送广播时action应该保持一致
private static final String DYNC_BROADCAST = "com.ys.broadcasttest.MyReceiver";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
button = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
button4 = (Button) findViewById(R.id.button4);
broadcastRegister(); //1注册广播
button.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
button4.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
sendBroadcastVoid(); //发送广播
break;
case R.id.button2:
break;
case R.id.button3:
sendBroadcastVoid3();
break;
case R.id.button4:
sendBroadcastVoid4(); //发送广播
break;
}
}
/**
* 注册广播 核心代码 动态自定义广播 (标准广播)
*/
private void broadcastRegister() {
myReceiver = new MyReceiver(); //1 实列化(自定义)广播类
IntentFilter intentFilter = new IntentFilter(); //意图过滤器实例化 用来过滤"动作"
intentFilter.addAction(DYNC_BROADCAST); //添加 广播的动作
registerReceiver(myReceiver, intentFilter); //注册广播
}
/**
* 发送广播 动态注册自定义广播(标准广播) 不是系统广播就要自己去发送
*/
private void sendBroadcastVoid() {
Intent intent = new Intent();
intent.setAction(DYNC_BROADCAST); //为意图添加广播动作
intent.putExtra("key","广播通过intent可以携带的信息:赖建文---xxx");
sendBroadcast(intent);
}
private static final String DYNC_BROADCAST3 = "com.ys.broadcasttest.ys2019"; //随便叫什么
/**
* 静态注册自定义广播(标准广播)
*/
private void sendBroadcastVoid3() {
Intent intent = new Intent();
intent.setAction(DYNC_BROADCAST3);
//当自定义的静态注册广播接收不到 时 要指定包名 与 类名setComponent
intent.setComponent(new ComponentName("com.ys.broadcasttest","com.ys.broadcasttest.staticReceiverDIY"));
sendBroadcast(intent);
}
/**
* 发送广播 动态注册自定义广播(有序广播) 不是系统广播就要自己去发送
* 有序广播就时 使用 sendOrderedBroadcast(intent,null);发送
* 如果在onReceiver 中调用了 abortBroadcast方法,表示截断该广播后序广播都接收不到了
*/
private void sendBroadcastVoid4() {
Intent intent = new Intent();
intent.setAction(DYNC_BROADCAST); //为意图添加广播动作
intent.putExtra("key","动态注册的自定义广播 !!!有序广播");
// 发送有序广播 意图 接收的权限
sendOrderedBroadcast(intent,null);
}
/**
* 取消广播 销毁广播 动态广播注册一定要在 重写onDestroy 并取消广播
*/
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver); //取消广播
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="动态注册自定义广播(标准广播)"
tools:layout_editor_absoluteX="151dp"
tools:layout_editor_absoluteY="295dp" />
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="动态注册自定义广播(有序广播)" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="静态注册系统广播 开机自启实现 不用点击" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="静态注册自定义广播(标准广播)" />
</LinearLayout>
3:广播按范围划分可以划分为
1:系统全局广播
2:本地广播
1:前面介绍的就是系统的全局广播,会播整个手机的所有应用截取到,有些不安全
2:本地广播 只在app内部进行传递,并且也只接收来自app内部的发出的广播,这样安全性更高
这样: 1 不用担心机密数据泄露 2不需要担心会有安全漏洞 3:本地广播比系统全局广播更加高效
特殊性: 本地广播是无法通过静态注册的方式来接收的。只能动态注册
主要使用LocalBroadcastManger 来对广播进行管理 发送和注册
实列:
private IntentFilter filter;
private LocalBroadcastManager localBroadcastManager;
private LocalReceiver localReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(MainActivity.this); // 获取实例
mButton = (Button) findViewById(R.id.send_broadcast_button);
mButtonLocal = (Button) findViewById(R.id.send_localbroadcast_button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setAction("static_broadcast");
//sendBroadcast(intent);
sendOrderedBroadcast(intent, null); // 发送有序广播
}
});
mButtonLocal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
filter = new IntentFilter();
filter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, filter); // 注册本地广播监听器
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "成功接收本地广播!", Toast.LENGTH_LONG).show();
}
};
@Override
protected void onDestroy() {
localBroadcastManager.unregisterReceiver(localReceiver);
super.onDestroy();
}
拓展:
註冊方式:
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,new IntentFilter(broadcast));
註銷方式:
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
傳送方式:
LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(intent);
完整程式碼: MainActivity.java
package com.example.cheng.broadcastreciver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String broadcast = "broadcast";
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(broadcast);
intent.putExtra("str", "sendBroadcase");
LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(intent);
}
});
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,new IntentFilter(broadcast));
}
private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,intent.getStringExtra("str"),Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
}
}