Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android四大组件之广播——详解全局BroadcastReceiver #221

Open
soapgu opened this issue Aug 16, 2023 · 0 comments
Open

Android四大组件之广播——详解全局BroadcastReceiver #221

soapgu opened this issue Aug 16, 2023 · 0 comments
Labels

Comments

@soapgu
Copy link
Owner

soapgu commented Aug 16, 2023

  • 使用场景一:系统广播接收

这也是最初开始用BroadcastReceiver的场景。
比如android.intent.action.BOOT_COMPLETED使用最常见,用来开机启动。
也有ACTION_PACKAGE_REPLACED等广播

这确实是是一种非常方便方式,但是隐式广播是一种不针对任何app的广播。任何应用都可以订阅,如果滥用会严重影响系统性能,只是目前只有系统广播可以订阅。

  • 使用场景二:独立接受处理广播

其实90%的场景我们都使用上下文广播接收器,他有两大优点

  1. 限制少,应用可以在运行时使用 Context.registerReceiver() 为任意广播(不管是隐式还是显式)注册接收器。

  2. 不用注册AndroidManifest.xml,只要注意及时释放资源即可。

但是也有一种情况是一定要用独立的BroadcastReceiver的。
比如你要执行的操作其实是一个后台操作,并不“依附”于任何一个界面组件。

  • 使用显式广播及关注BroadcastReceiver的限制

当使用自定义的隐式广播发送,而使用清单注册的BroadcastReceiver收不到!这是怎么回复?

那是因为隐式广播已经在API 24以后被限制了

  • 不指定应用的隐式广播只有系统广播可以接收
  • 指定应用的隐式广播也能接受

比如下面的代码

Intent intent = new Intent();
        intent.setAction(broadcastName);
        intent.putExtra( "data", data);
        intent.setPackage(this.getPackageName());
         sendBroadcast(intent);
        }

intent.setPackage这个方法一定要加,否则就是“没坐标”广播,谁都收不到。

  • 显示广播能接收

好像我们从来没用过显示广播
是这样的,顾名思义就是“点对点”,直接定义BroadcastReceiver为接收目标。

比如先写好Receiver

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = String.format( "receive broadcast data:%s from receiver", intent.getStringExtra("data"));
        Toast.makeText(context, message, Toast.LENGTH_LONG).show();
    }
}

发送端这样写

Intent intent = new Intent();
        intent.setAction(broadcastName);
        intent.putExtra( "data", data);
        intent.setComponent( new ComponentName(this, MyBroadcastReceiver.class));
       sendBroadcast(intent);

写上setComponent即可,就和写邮件的邮箱地址一样。

接下来关键是注册部分

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyBroadcast"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".MyBroadcastReceiver"  android:exported="false">
        </receiver>

    </application>
</manifest>

原来隐式广播还要写intent-filter过滤Action,显示广播就完全不用,只要写name就行了

  • 开脑洞之能否接收LocalBroadcastManager发送的本地广播

接下来是脑洞时间

看来也有人这么无聊。答案是否,LocalBroadcastManager就是专门能上下文广播接收器用的!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant