静态广播与动态广播的区别

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数据从广播发出端传输到广播接收端
            }
        });
  1. 由上述onClick中的代码可知,我们要先构建intent,Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来响应。
  2. intent.setPackage(“com.example.mybroadcast”); 接着对intent设置包名
  3. intent.putExtra(“name”,“953985137”);用于在程序中传递值,可以把name标识的值953985137传递到广播接收处;与之对应的是intent.getStringExtra(“name”),将intent的name标识的值取出来;
  4. setAction(“mxp”),action是用来表现意图的行动,里面的值(mxp)可以随意设置,但是需要和下文AndroidManifest中添加的一样
  5. 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);


            }
        });
  1. 首先要创建IntentFilter,中文是意图过滤器;在里面添加了Action作为过滤的标识;
  2. 接着创建广播接收器MyBroadcastReceiver ,这个类也是静态广播写的那个广播接收器,是一样的。
  3. 然后注册广播接收器registerReceiver(myBroadcastReceiver,intentFilter);
    通过这个方法,将广播接收器中加入过滤装置,只有intent中设置的action的值和intentFilter中action设置的值能对应上才能启动广播接收器;
  4. 然后设置intent,可以注意到我设置的值和IntentFilter中的一样;
    动态广播也可以用intent.putExtra(“name”,“953985137”);传值
  5. 最后还可以添加FLAG,例如 intent.setFlags(FLAG_RECEIVER_REGISTERED_ONLY);
    添加上了FLAG_RECEIVER_REGISTERED_ONLY的flag,这样就保证了这类广播只能通过动态注册的广播接收者来接收。

写动态广播不需要在AndroidManifest中声明,因为使用registerReceiver已经注册过了,相当于声明过了。
一个程序可以写多个广播接收器