美文网首页
日更挑战-安卓广播接收者

日更挑战-安卓广播接收者

作者: 愿你我皆是黑马 | 来源:发表于2021-06-15 23:38 被阅读0次

    越不懂的越爱装
    大家都同等:IT世界没有难不难,只有是否了解过

    挑战目录

    什么是安卓中的广播

    是安卓程序之间或单个程序内部传递消息的机制之一。
    按发送者(广播来源)分为系统广播和自定义广播。
    按注册方式分为静态注册广播和动态注册广播。
    按功能分为系统广播、默认广播、有序广播、粘性广播(废弃)、App应用内广播。


    系统广播和自定义广播

    • 系统广播

      发送者为系统自己发送,注册和接收的实现和自定义广播一致。

    • 为什么要使用自定义广播而不是自己实现广播模式


    静态注册和动态注册广播

    • 静态注册
      常驻,不受任何组件的生命周期影响

      适用于需要时刻监听的广播

      在xml文件中生命注册

      耗电,占内存

      1. 定义广播

        class 静态广播注册():BroadcastReceiver() {
        
            override fun onReceive(p0: Context?, p1: Intent?) {
                Toast.makeText(p0,"广播接收", Toast.LENGTH_SHORT).show()
            }
        }
        
      2. 注册广播

        <?xml version="1.0" encoding="utf-8"?>
        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
            <application>
                <receiver android:name=".静态广播注册"
                    android:enabled="true"  <!--  -->
                    android:exported="true" <!-- 是否接收其他应用的广播 -->
                    android:permission="mypermission" <!-- 具有相应权限的发送者,才能往这个接收者发送广播 -->
                    >  
                    <intent-filter>
                        <action android:name="MyTest"/>  <!-- action -->
                    </intent-filter>
                </receiver>
            </application>
        </manifest>
        
      3. 发送广播

        class MainActivity : AppCompatActivity() {
        
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.activity_main)
            }
        
            fun sendBroadcastReceiver(view: View) {
                tv_sendBroadcastReceiver.setOnClickListener {
                    val intent = Intent()
                    intent.action = "MyTest"
                    intent.putExtra("参数","参数值")
                    sendBroadcast(intent)
                }
            }
        }
        
    • 动态注册
      非常驻广播
      在代码中动态声明
      跟随组件生命周期变化
      适用于需要特定时刻监听的广播

      class MainActivity : AppCompatActivity() {
      
          private lateinit var receiver:TestReceiver
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_main)
              val intentFilter = IntentFilter()
              intentFilter.addAction("test")
              receiver = TestReceiver()
              //动态注册广播
              registerReceiver(receiver,intentFilter)
          }
      
            //xml布局中的点击事件,发送广播
          fun sendBroadcastReceiver(view: View) {
              tv_sendBroadcastReceiver.setOnClickListener {
                  val intent = Intent()
                  intent.action = "test"
                  intent.putExtra("参数","参数值")
                  sendBroadcast(intent)
              }
          }
      
            //及时注销广播,防止内存泄露
          override fun onPause() {
              super.onPause()
              unregisterReceiver(receiver) //及时注销广播,防止内存泄露
          }
      
          class TestReceiver : BroadcastReceiver() {
              override fun onReceive(p0: Context?, p1: Intent?) {
                  Toast.makeText(p0,"广播接收",Toast.LENGTH_SHORT).show()
                }
            }
        }
      
      • 动态注册在何时注销比较好
        尽量在onResume注册,在onPause注销。

        因为onPause是App死亡前肯定会执行的方法。但是当系统内存不足时,App在执行完onPause后就会被销毁,来不及执行onStop、onDestory方法。


    系统广播、默认广播、有序广播、粘性广播(废弃)、App应用内广播

    • 系统广播

    • 默认广播

      1. 特点:
        • 所有的接受者之间是异步的
        • 接收者相互之间不会有影响
        • 接收者无法阻止其他接收者接收
        • 优先级、setResultExtras(Bundle())、abortBroadcast等有序广播API的设置无效
    • 有序广播

      1. 特点:

        • 通过sendOrderedBroadcast(intent,null)发送,第二个参数为权限,传null表示不需要任何权限
        • 根据优先级(-1000到1000)从大到小接收广播
        • 同优先级动态注册的先接收
        • 同优先级先注册的先接收
        • 通过xml的intent-filter的priority或者intentFilter.priority=xx指定优先级
        • 在接收方法onReceive里可以使用setResultExtras(Bundle())设置下一个接收者的接收到的数据
        • 在接收方法onReceive里可以使用abortBroadcast终止广播
        • 在接收方法onReceive里可以使用resultData传递字符串数据
      2. 有序广播sendOrderedBroadcast(intent,null)的权限参数:?

    • 粘性广播(废弃)

    • App应用内广播

      1. 特点:
        • 广播不会发送
      2. 关于,发送本地广播
        • 将上面实现广播的代码的注册、取消注册、发送中的context参数改为 LocalBroadcastManager.getInstance(this)
      3. 关于,接收时防止恶意接收到特殊构造的广播攻击:
        • 将exported设置为false,使得只接收本应用广播
        • 发送和接收时,增加权限字段,也可防止
        • 发送广播时通过intent.setPackage(receiverPackageName)指定广播接收器对应的包名

    onReceive(p0: Context?, p1: Intent?)方法中的Context

    • 本地广播+动态注册:Activity Context
    • 本地广播+静态注册:Application Context
    • 非本地广播+动态注册:Activity Context
    • 非本地广播+静态注册:ReceiverRestricted Context

    onReceive(p0: Context?, p1: Intent?)方法中的Intent


    安卓8.0后广播的改动

    • 在AndroidManifest.xml中注册无效的广播
      1. 屏幕的开、关广播
      2. 电量的变化广播
      3. 等等
    • 有序广播的接收者必须配置优先级,防止接收顺序错乱
    • 只能通过动态注册的方式,实现有序广播。

    安卓广播源码实现

    • 静态广播注册原理

      1. 在系统启动的时候通过PackageManagerService扫描已安装应用进行注册。具体扫描代码如下:

    相关文章

      网友评论

          本文标题:日更挑战-安卓广播接收者

          本文链接:https://www.haomeiwen.com/subject/vsntyltx.html