静态广播与动态广播的区别
1、动态注册的广播永远要快于静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低
2、生存期,静态广播的生存期可以比动态广播的长很多,因为静态广播很多都是用来对系统时间进行监听,比如我们可以监听手机开机。而动态广播会随着context的终止而终止
3、动态广播无需在AndroidManifest.xml中声明即可直接使用,也即动态;而静态广播则需要,有时候还要在AndroidManifest.xml中加上一些权限的声明
一、静态广播
首先我们先在布局activity_main.xml设定两个按钮,一个表示静态广播,另一个表示动态广播
<?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"
tools:context=".MainActivity">
<Button
android:id="@+id/staticBroadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="静态广播!"
/>
<Button
android:id="@+id/dynamicBroadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="动态广播"
/>
</LinearLayout>
然后在Mainactivity.java中设置按钮的监听
public class MainActivity extends AppCompatActivity {
private Button staticBroadcast,dynamicBroadcast;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 静态注册,不随程序关闭而失效
*/
staticBroadcast = findViewById(R.id.staticBroadcast);
staticBroadcast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: 静态广播触发");
Intent intent = new Intent();
intent.setPackage("com.example.mybroadcast");
intent.setAction("mxp"); //AndroidManifest添加action
intent.putExtra("name","953985137");
sendBroadcast(intent);
// 1、静态广播一定要加包名setPackage("com.example.mybroadcast") 包名是自己demo的路径
// 2、setAction(value),value可以写任意值,但是要和AndroidManifest添加的<action android:name="value" />中的value一致
// 3、putExtra("name","953985137")与getStringExtra(name)对应 由name确定的value数据从广播发出端传输到广播接收端
}
});
- 由上述onClick中的代码可知,我们要先构建intent,Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来响应。
- intent.setPackage(“com.example.mybroadcast”); 接着对intent设置包名
- intent.putExtra(“name”,“953985137”);用于在程序中传递值,可以把name标识的值953985137传递到广播接收处;与之对应的是intent.getStringExtra(“name”),将intent的name标识的值取出来;
- setAction(“mxp”),action是用来表现意图的行动,里面的值(mxp)可以随意设置,但是需要和下文AndroidManifest中添加的一样
- sendBroadcast(intent);启动广播
AndroidManifest代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mybroadcast">
<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=".MyBroadcastReceiver">
<intent-filter>
<action android:name="mxp" />
</intent-filter>
</receiver>
</application>
</manifest>
真正需要添加的就是receiver中的代码块;其中action的值mxp随意设置,但是要和上文intent.setAction中的值设置为一样的。
目的在于:这个值是用来识别是谁发出广播的标识,也是触发广播的条件,如果intent中Action的值在AndroidManifest中找不到,那么这个intent不会触发广播;
除此之外,我们还要创建一个.Java文件,名称自己定,我这里叫MyBroadcastReceiver,也就是广播接收器,广播从Mainactivity发出传递到广播接收器,接收器中可以写很多针对不同广播内容的处理方法
MyBroadcastReceiver.java代码
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: 广播到了");
Toast toast = Toast.makeText(context,"QQ号"+intent.getStringExtra("name"),Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP,0,0);
toast.show();
//abortBroadcast();//中断广播
}
}
满足触发条件的广播触发后程序就会跳转到广播接收器这,静态动态广播都可以传递到此接收器中;执行里面的处理方法,intent.getString()可以获取传递过来的值;
动态广播
Mainactivity中代码
/**
* 动态注册,随程序关闭而失效
*/
dynamicBroadcast=findViewById(R.id.dynamicBroadcast);
dynamicBroadcast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: 动态广播触发");
//设定好广播的标准
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.big"); // intentFilter.addAction 和 new Intent 的action一样就能开启广播,不同则不能开启
//创建广播接收器
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
registerReceiver(myBroadcastReceiver,intentFilter); //将广播放入广播接收器中,相当于初始化成功广播接收器 注册广播
//触发广播事件
Intent intent = new Intent();
intent.setAction("android.big");
intent.setFlags(FLAG_RECEIVER_REGISTERED_ONLY);
sendBroadcast(intent);
}
});
- 首先要创建IntentFilter,中文是意图过滤器;在里面添加了Action作为过滤的标识;
- 接着创建广播接收器MyBroadcastReceiver ,这个类也是静态广播写的那个广播接收器,是一样的。
- 然后注册广播接收器registerReceiver(myBroadcastReceiver,intentFilter);
通过这个方法,将广播接收器中加入过滤装置,只有intent中设置的action的值和intentFilter中action设置的值能对应上才能启动广播接收器; - 然后设置intent,可以注意到我设置的值和IntentFilter中的一样;
动态广播也可以用intent.putExtra(“name”,“953985137”);传值 - 最后还可以添加FLAG,例如 intent.setFlags(FLAG_RECEIVER_REGISTERED_ONLY);
添加上了FLAG_RECEIVER_REGISTERED_ONLY的flag,这样就保证了这类广播只能通过动态注册的广播接收者来接收。
写动态广播不需要在AndroidManifest中声明,因为使用registerReceiver已经注册过了,相当于声明过了。
一个程序可以写多个广播接收器