您好,欢迎来到花生壳b2b外贸网信息发布平台!
18951535724
  • 开发者社区

       2026-05-11 网络整理佚名780
    核心提示:Android应用可收发广播,类似发布 - 订阅模式。系统事件会触发系统广播,应用也能发自定义广播。介绍系统广播、接收方式、发送方式、权限限制及安全最佳方案等内容。

    大家好,又见面了,我是你们的朋友全栈君。

    Android应用程序可以发送广播,也可以接收Android系统或者其它应用发出的广播,这跟发布-订阅设计模式很相似。当一些受到关心的事件发生后,广播会被自动发送。举例来说,当一些系统事件(如开机,设备开始充电等)发生,Android系统会发送广播。应用程序也可以发送自定义的广播,比如当某个应用关注的事件(如数据更新等)发生后可以发送广播提醒它。

    系统广播

    当一系列系统事件发生的时候,系统会自动发送广播,比如飞行模式的切换。系统广播会发送给所有注册监听广播的应用。

    广播消息封装在一个Intent对象中,其中的action属性标识的事件的类型(比如android.intent.action.AIRPLANE_MODE),可能在intent的附件字段还包含了附加的信息。比如,用于表示飞行模式的intent包含一个附加的布尔字段来表示飞行模式的状态是开启还是关闭。

    如果想要具体了解如何如何读取一个intent并且获取附加字段,参阅

    参阅Android SDK中的BROADCAST_ACTIONS.TXT来了解所有系统广播的action。每一个系统广播都有一个常量与其绑定。比如,常量ACTION_AIRPLANE_MODE_CHANGED表示android.intent.action.AIRPLANE_MODE。每一个广播的action的文档都在与其关联的常量域中。

    系统广播的变化

    android qq消息广播

    Android 7.0或更高版本不再发送下列系统广播,这项优化会影响所有的应用程序,而不只是那些针对Android 7.0开发的程序。

    针对Android 7.0(API level 24)或更新版本开发的应用必须在程序中使用 ACTION_NEW_PICTURE ACTION_NEW_VIDEO 注册监听下列的广播,在程序清单中声明不再有效。

    接收广播

    应用程序可以使用两种方式接收广播:在应用清单中定义一个广播接收器;在程序中注册一个广播接收器。

    静态广播接收器

    要定义一个静态广播接收器,执行下面的步骤:

    当应用程序安装的时候,软件包管理器会在系统中注册广播接收器。之后这个广播接收器就变成了你的应用程序中一个独立的入口,这就意味着如果你的应用程序不在运行,系统可以启动你的程序并传递广播。

    系统会创建一个新的BroadcastReceiver组件对象来处理接收到的广播。这个对象只在调用onReceive(Context, Intent)方法期间有效。一旦从该方法返回,系统就认为这个组件对象已经失效。

    动态广播接收器

    android qq消息广播

    要注册一个上下文相关的动态广播接收器,执行以下步骤:

    对进程状态的影响

    你的广播接收器的状态会影响它所在的进程的状态,转而会影响进程被系统杀死的可能性。比如,当一个进程执行一个广播接收器(执行onReceive()方法中的代码),它会被当作一个前台进程。除非内存极度匮乏,否则系统会一直让该进程运行。

    然而,一旦从onReceive()返回,广播接收器就不再处于激活状态,它的宿主进程也就跟其它的普通进程具有相同的优先级。如果那个进程只拥有一个在应用清单中定义的接收器,那么当从onReceive()返回后,系统会把它当作一个低优先级的进程,当其它优先级更高的进程需要更多内存的时候,它就可能被杀掉。

    鉴于这个原因,你不应该在一个广播接收器中启动一个长时间在后台运行的线程。当从onReceive()返回后,系统可能会杀掉进程来回收内存,这会结束所有运行在这个进程中的线程。为了避免这种情况,你要么调用goAsync()(如果你希望能够长时间在后台线程中运行广播接收器),要么在接收器中使用JobScheduler调度一个JobService。这样系统就直到你的进程还在继续执行任务。参阅 Processes and Application Life Cycle来获取更多信息。

    下面的代码片段展示了使用goAsync()来标识进程需要更多时间来完成任务。如果你要执行的任务会造成UI阻塞(>16ms),这种方式非常有效。

    ```
    public class MyBroadcastReceiver extends BroadcastReceiver {
        private static final String TAG = "MyBroadcastReceiver";
        @Override
        public void onReceive(final Context context, final Intent intent) {
            final PendingResult pendingResult = goAsync();
            AsyncTask asyncTask = new AsyncTask() {
                @Override
                protected String doInBackground(String... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("Action: " + intent.getAction() + "\n");
                    sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
                    Log.d(TAG, log);
                    // Must call finish() so the BroadcastReceiver can be recycled.
                    pendingResult.finish();
                    return data;
                }
            };
            asyncTask.execute();
        }
    }
    ```

    发送广播

    android qq消息广播

    Android提供了三种发送广播的方式:

    下面的代码片段示范了如何通过创建Intent并且调用sendBroadcast(Intent)来发送广播:

    Intent intent = new Intent();
    intent.setAction("com.example.broadcast.MY_NOTIFICATION");
    intent.putExtra("data","Notice me senpai!");
    sendBroadcast(intent);

    广播消息被封装在一个Intent对象中。intent的action属性必须提供应用的包名并且能够唯一地标识一个广播事件。你可以通过调用putExtra(String, Bundle)来附加额外的xinxi。你也可以通过调用intent的setPackage(String)方法来将广播范围限定在某个组织的一系列应用的范围之内。

    注意:虽然intents同时被用来发送广播和启动Activity,但是这些行为之间并没有任何关联。广播接收器无法捕捉到用来启动Activity的intent;同样地,当你广播一个intent,你也无法启动一个Activity。

    通过权限限制广播的收发

    权限机制可以让你将广播的范围限制在一系列拥有特定权限的应用之间。你既可以限制发送发,也可以限制接收方。

    带权限发送

    android qq消息广播

    当你调用sendBroadcast(Intent, String)或者 sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)时,你可以指定一个权限参数。只有应用在应用清单中申请了那个权限,其中的receiver才能接收到广播。比如下面的代码发送了一个带权限的广播:

    sendBroadcast(new Intent("com.example.NOTIFY"),
                  Manifest.permission.SEND_SMS);

    要接收这个广播,应用必须申请下面的权限:

    你既可以指定一个系统中已经存在的权限,比如SEND_SMS,也可以用自定义一个权限。关于权限的详情请参考System Permissions。

    带权限接收

    如果你在注册receiver的时候指定了一个权限参数,那么只有申请了相应权限的应用才能够向你的receiver发送广播。

    比如,假设你的receiver在应用清单中这样定义:

    
        
            
        
    

    android qq消息广播

    或者在代码中这样定义一个上下文相关的receiver:

    IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
    registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null );

    那么,如果你要向这些receiver发送广播,发送方必须申请如下的权限:

    安全性和最佳使用方案

    下面是关于发送和接收广播的安全性考虑和最佳使用方案:

    当你注册一个receiver后,任何应用都可以向你发送具有潜在恶意信息的广播。有三种方式来限制广播的发送发: 广播的action标志是全局的,确保action的值和其它字符串的值是在你自己的命名空间中,否则你可能会不小心与其它应用发生冲突。 因为receiver的onReceive(Context, Intent)方法运行在主线程中,所以它必须能够很快地执行并返回。如果你需要执行一个耗时的操作,要小心使用子线程或者后台服务,因为当onReceive(Context, Intent)函数返回之后,系统随时会杀死你的进程。要了解更多信息,参考对进程的影响小节,要执行耗时的操作,我们建议: 不要在receiver中启动Activity,因为这严重影响用户体验,尤其是当存在多个receiver。可以通过显示一个通知来代替。

    发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/148542.html原文链接:https://javaforall.cn

     
    举报收藏 0打赏 0评论 0
    更多>相关评论
    暂时没有评论,来说点什么吧
    更多>同类百科知识
    推荐图文
    推荐百科知识