欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发之广播的基本使用说明

程序员文章站 2022-05-04 09:25:54
1、android广播发送及广播类型 广播发送的基本代码: intent intent = new intent(); intent.setaction(constant.wait_broa...

1、android广播发送及广播类型

广播发送的基本代码:

intent intent =  new intent();
intent.setaction(constant.wait_broadcast_action);
context.sendbroadcast(intent);

根据广播的发送方式,可以将其分为以下几种类型:

1)普通广播 normal broadcast

2)广播 system broadcast

3) 有序广播 ordered broadcast

4)粘性广播 sticky broadcast (在android 5.0/api 21中不推荐使用,有序粘性广播也已经不推荐使用)

5)应用内广播 local broadcast(使用localbroadcastmanager,只能在应用内使用,不能跨进程使用。)

1)普通广播 normal broadcast

开发者自己定义的intent,以context.sendbroadcast(...)或者context.sendbroadcastasuser(...)形式发送。

具体可以使用的方法有:

sendbroadcast(...):

①sendbroadcast(@requirespermission intent intent);

②sendbroadcast(@requirespermission intent intent, @nullable string receiverpermission);

③sendbroadcast(intent intent, @nullable string receiverpermission, @nullable bundle options);

④sendbroadcast(intent intent, string receiverpermission, int appop);

sendboadcastasuser(...)

①sendbroadcastasuser(@requirespermission intent intent, userhandle user);

②sendbroadcastasuser(@requirespermission intent intent, userhandle user, @nullable string receiverpermission);

③sendbroadcastasuser(@requirespermission intent intent, userhandle user, @nullable string receiverpermission, int appop);

2)系统广播 system broadcast

android系统内置了多个广播,涉及到手机的基本操作,基本上都会发出相应的系统广播。

系统广播在系统内部当特定事件发生时,由系统发出。

3)有序广播 ordered broadcast

有序广播是针对广播接收者(broadcastreceiver)而言,按照先后顺序接收的。

先后顺序判断标准为:按照priority由大到小排序;有相同priority的动态广播和静态广播,动态广播会排在前面。

4)粘性广播(sticky broadcast)

已经在android 5.0/api 21中不推荐使用

5)应用内广播(local broadcast)

用localbroadcastmanager统一处理app应用内的广播问题。

android广播可以跨进程甚至跨app发送,会造成一下问题:

①其他应用可能会针对当前app,发送与当前app intent-filter一致的广播,导致app不断的接收和处理;

②其他应用可以注册与当前app intent-filter一致的广播,用于接收广播信息。

以上两种情况都存在安全隐患,常见的增加安全性的方案是:

①本地app内部发送和接收的广播,将exported属性设为false。

②在发送和接收广播时,增加上相应的permission,用于权限验证。

③发送广播时,指定广播接收器所在的包名

2、广播发送和接收的原理

除应用内广播,其他广播发送和接收原理

①继承broadcastreceiver,重写onreceive()方法;

②通过binder机制向activitymanagerservice注册广播

③通过binder机制向activitymanagerservice发送广播

④ams查找符合条件(intentfilter/permission)的broadcastreceiver,将广播发送到broadcastreceiver所在的消息队列中。

⑤broadcastreceiver所在的队列收到此广播后,回调onreceive()方法。

应用内广播,发送和接收原理与普通广播基本一致,将activitymanagerservice换为localmanagerservice控制广播的接收和发送等流程。

3、广播数据的限制(未验证,待验证)

广播传输数据大小应该尽可能的小。不能太大。图片或者太长的字符串应该以别的方式传递。

进程内,可以用eventbus,文件缓存,磁盘缓存。

官网上对transationtoolargeexception有如下说明:

transactiontoolargeexception

the binder transaction failed because it was too large.

during a remote procedure call, the arguments and the return value of the call are transferred asparcelobjects stored in the binder transaction buffer. if the arguments or the return value are too large to fit in the transaction buffer, then the call will fail andtransactiontoolargeexceptionwill be thrown.

the binder transaction buffer has a limited fixed size, currently 1mb, which is shared by all transactions in progress for the process. consequently this exception can be thrown when there are many transactions in progress even when most of the inpidual transactions are of moderate size.

there are two possible outcomes when a remote procedure call throwstransactiontoolargeexception. either the client was unable to send its request to the service (most likely if the arguments were too large to fit in the transaction buffer), or the service was unable to send its response back to the client (most likely if the return value was too large to fit in the transaction buffer). it is not possible to tell which of these outcomes actually occurred. the client should assume that a partial failure occurred.

the key to avoidingtransactiontoolargeexceptionis to keep all transactions relatively small. try to minimize the amount of memory needed to create aparcelfor the arguments and the return value of the remote procedure call. avoid transferring huge arrays of strings or large bitmaps. if possible, try to break up big requests into smaller pieces.

意思大概是说

通过binder缓冲区中的parcel对象进行传输。binder事务缓冲区具有有限的固定大小,当前为1mb。

由当前进程正在进行的所有事务共享。因此,即使大多数单个事务的大小适中,当有许多事务正在进行时,也会抛出此异常。

当抛出transactiontoolargeexception时,有两种可能得原因。客户端无法将其请求发送到服务(可能因为参数太大而无法保存到事务缓冲区中),或者服务无法将其响应发送回客户端(可能因为返回值为太大而无法保存到事务缓冲区中)。

避免transactiontoolargeexception的关键是保持所有事务相对较小。

避免传输大量字符串或大位图。如果可能的话,尝试将大量请求分解成更小的部分。