导航:首页 > 操作系统 > android广播缺点

android广播缺点

发布时间:2024-02-08 18:42:08

❶ 为什么android要使用各种BroadcastReceiver

作为Android四大组件之一的BroadcastReceiver(广播接收者),同Activity(活动)一样,经常被大家用到,网上也是一堆对它的讲解,那么为什么Android要用广播接收者这种机制呢?
广播分为:普通广播和有序广播
1.Normal broadcasts(普通广播):Normal broadcasts是完全异步的可以同一时间被所有的接收者接收到。消息的传递效率比较高。但缺点是接收者不能将接收的消息的处理信息传递给下一个接收者也不能停止消息的传播。可以利用Context.sendBroadcast发送。
2.Ordered broadcasts(有序广播):Ordered broadcasts的接收者按照一定的优先级进行消息的接收。一次传送到一个接收器。 随着每个接收器依次执行,它可以将结果传播到下一个接收器,或者它可以完全中止广播,使得它不会被传递到其他接收器。 命令接收器运行可以用匹配的意图过滤器的android:priority属性控制; 具有相同优先级的接收器将以任意顺序运行。可以利用Context.sendOrderedBroadcast发送。
官网上介绍广播是用的监听系统网络状况的例子,其实关键字在于“监听”。
(1) 创建广播接收者
BroadcastReceiver是一个抽象类,所以我们要创建自己的广播接收者就要继承它,继承后会有提示重写onReceive方法。
public class NetworkBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
if (activeNetwork != null && activeNetwork.isAvailable()) {
Toast.makeText(context, "有网络连接", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "无网络连接", Toast.LENGTH_SHORT).show();
}
}
}
}

广播接收者的生命周期是从接收广播开始,到onRecevier方法执行完成结束,时间很短,一般不允许处理大批量耗时操作。这里顺便给出打印NetworkInfo的信息以供参考:
NetworkInfo:
type: WIFI[,type_ext: WIFI],
state: CONNECTED/CONNECTED,
reason: (unspecified),
extra: "TP-LINK_EFE8",
roaming: false,
failover: false,
isAvailable: true,
: false,
isIpv4Connected: true,
isIpv6Connected: false

[type: MOBILE[LTE],
state: CONNECTED/CONNECTED,
reason: connected,
extra: cmnet,
roaming: false,
failover: false,
isAvailable: true,
: false]

(2) 静态注册广播
静态注册广播,需要在AndroidManifest.xml中,添加<recevier/> 标签,将广播接收者注册到应用中。要添加过滤器IntentFilter,由于系统网络变化时会发送ConnectivityManager.CONNECTIVITY_ACTION ("android.net.conn.CONNECTIVITY_CHANGE")的广播,所以我们要监听这条广播。
<receiver android:name=".NetworkBroadcastReceiver">
<intent-filter android:priority="1000">
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>

这里priority代表的是执行顺序的优先级,取值[-1000,1000],后面的有序广播会讲到。
(3) 动态注册广播
i.意图过滤器 IntentFilter 用于给BroadcastReceiver绑定监听广播类型
ii.自定义的BroadcastReceiver,例如上文的
iii.注册方法 Context.registerReceiver(Receiver, IntentFilter)
iv.反注册方法 unregisterReceiver(Receiver)
IntentFilter mFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
mReceiver = new ();
registerReceiver(mReceiver, mFilter);

@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}

这段代码是成对出现的,可以在onCreate的时候注册,在onDestroy的时候反注册,也可以在onResume和onPause中执行这写方法。不过Google API推荐的做法,在activity的onResume()中注册,在onPause()反注册。效果是当界面pause时,就不接收广播,从而减少不必要的系统开销。还有就是一定要主动反注册你的广播,否则会出现异常。
动态注册和静态注册的差别:动态注册后,广播接收者会依赖Activity的生命周期,而静态注册的广播不会,只要是系统有发出的广播,它都会接收,与程序是否启动无关。
(4) 发送普通广播
具体使用的方法是sendBroadcast(Intent intent),通过隐式调用就可以,注意action是你自定义的,意思就是不可以发送系统广播,我试了,直接就崩了。
Intent intent = new Intent();
intent.setAction("com.fleming.chen.mybroadcast");
sendBroadcast(intent);

针对(3)(4)两点,如果你要用到的广播仅仅是应用里的,那么你可以用LocalBroadcastManager这个类,它与上述描述中的区别在于:
LocalBroadcastManager.getInstance(context).registerReceiver(mReceiver, mFilter);

LocalBroadcastManager.getInstance(context).unregisterReceiver(mReceiver);

LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

通过sendBroadcast发送的广播,不会被通过LocalBroadcastManager类注册的广播接收者接收,反之也是如此,两者是不可以”互通友谊“的,推荐使用LocalBroadcastManager来管理广播。
(5) 发送有序广播
上面讲了那么多都是普通广播,那什么又是有序广播呢?
有序广播关键在于这类广播是有序的,上文中提到priority,这是IntentFilter的属性,用来让不同的广播拥有不同的执行顺序,即优先级不同。
定义三种不同优先级的广播接收者:
public class MyBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.fleming.chen.myreceiver")) {
String message = getResultData();
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
setResultData("这是修改后的数据");//第一个接收后处理一下,再交给下一个
}
}
}

public class MyBroadcastReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.fleming.chen.myreceiver")) {
String message = getResultData();//得到上一个的处理结果
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
abortBroadcast();//主动停止广播,不再继续传下去
}
}
}

public class MyBroadcastReceiver3 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.fleming.chen.myreceiver")) {
//此时虽然该广播接收者也监听了,不过也没有内容
Toast.makeText(context, getResultData(), Toast.LENGTH_SHORT).show();
}
}
}

<receiver android:name=".MyBroadcastReceiver" >
<intent-filter android:priority="1000">
<action android:name="com.fleming.chen.myreceiver"/>
</intent-filter>
</receiver>
<receiver android:name=".MyBroadcastReceiver2">
<intent-filter android:priority="0">
<action android:name="com.fleming.chen.myreceiver"/>
</intent-filter>
</receiver>
<receiver android:name=".MyBroadcastReceiver3">
<intent-filter android:priority="-1000">
<action android:name="com.fleming.chen.myreceiver"/>
</intent-filter>
</receiver>

Intent intent = new Intent();
intent.setAction("com.fleming.chen.myreceiver");
sendOrderedBroadcast(intent, null, null, null, 0, "这是初始的数据", null);

对于广播的内容,在Android 7.0上做了修改,即Project Svelte:后台优化
Android 7.0 移除了三项隐式广播,以帮助优化内存使用和电量消耗。此项变更很有必要,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用。删除这些广播可以显着提升设备性能和用户体验。
移动设备会经历频繁的连接变更,例如在 WLAN 和移动数据之间切换时。目前,可以通过在应用清单中注册一个接收器来侦听隐式 CONNECTIVITY_ACTION 广播,让应用能够监控这些变更。由于很多应用会注册接收此广播,因此单次网络切换即会导致所有应用被唤醒并同时处理此广播。
同理,在之前版本的 Android 中,应用可以注册接收来自其他应用(例如相机)的隐式 ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 广播。当用户使用相机应用拍摄照片时,这些应用即会被唤醒以处理广播。
为缓解这些问题,Android 7.0 应用了以下优化措施:
面向 Android 7.0 开发的应用不会收到 CONNECTIVITY_ACTION 广播,即使它们已有清单条目来请求接受这些事件的通知。在前台运行的应用如果使用 BroadcastReceiver 请求接收通知,则仍可以在主线程中侦听 CONNECTIVITY_CHANGE。
应用无法发送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 广播。此项优化会影响所有应用,而不仅仅是面向 Android 7.0 的应用。
如果您的应用使用任何 intent,您仍需要尽快移除它们的依赖关系,以正确适配 Android 7.0 设备。Android 框架提供多个解决方案来缓解对这些隐式广播的需求。例如,JobScheler API 提供了一个稳健可靠的机制来安排满足指定条件(例如连入无限流量网络)时所执行的网络操作。您甚至可以使用 JobScheler 来适应内容提供程序变化。
所以说,在Android的世界,到处都充满着广播,就是为了用来监听手机的各种状态,给用户提醒,这是一种很好的用户体验,不过任何事情都是如此,广播也不可以多用哦,

❷ 12、注册广播有几种方式,这些方式有何优缺点请谈谈Android引入广播机制的用意。

  1. 注册广播的分类:静态注册和动态注册。

    静态注册:在清单文件里直接注册,从app开启到app销毁,一直在接收广播,接收广播时间长,但是接收广播的优先级低于动态注册广播。

    动态注册:动态注册,动态销毁,从onCreate到取消注册,期间接收广播,接收广播时间是短且可控,接收广播的优先级高。例如:

    发送广播:
    Intent i = new Intent();
    i.setAction("ACTION_CLOSE");
    sendBroadcast(i);

    接受广播:
    onCreate(){

    //注册广播的接受者
    IntentFilter filter = new IntentFilter();
    filter.addAction("ACTION_CLOSE_ACTIVITY");
    receiver = new InnerReceiver();
    registerReceiver(receiver, filter);
    }

    private class InnerReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    //TODO 当前Activity接收到广播 需要做的事情
    }
    }
    }

    //注销广播

    @Override
    protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(receiver);
    }


2.引入广播的原因:

a) 不同的app之间传信通用

b)发出一条指定,需要多个Activity都需要有反应


注意:以上仅供参考,如有疑问,请追问,谢谢。

❸ android 注册广播有几种方式,这些方式有何优缺点

有两种注册广播方式:
1.常驻型广播
常驻型广播,当应用程序关闭了,如果有广播信息来,写的广播接收器同样的能接收到,它的注册方式就是在应用程序的AndroidManifast.xml 中进行注册,这种注册方式通常又被称作静态注册。这种方式可以理解为通过清单文件注册的广播是交给操作系统去处理的。示例代码如下:
AndroidManifest.xml中配置广播

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="spl.broadCastReceiver"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".BroadCastReceiverActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!--广播注册、name里面填写广播类的路径-->
<receiver android:name=".SmsBroadCastReceiver">
<intent-filter android:priority="20">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>

</application>

<uses-sdk android:minSdkVersion="7" />

<!-- 权限申请 -->
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>

</manifest>

2.非常驻型广播
非常驻型广播,当应用程序结束了,广播自然就没有了,比如在 Activity 中的 onCreate 或者 onResume 中注册广播接收者,在 onDestory 中注销广播接收者。这样广播接收者就一个非常驻型的了,这种注册方式也叫动态注册。这种方式可以理解为通过代码注册的广播是和注册者关联在一起的。比如写一个监听 SDcard 状态的广播接收者:
package cn.sunzn.mosecurity.activity;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Environment;

public class SDcard extends Activity {
SdcardStateChanageReceiver sdcardStateReceiver;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sdcardStateReceiver = new SdcardStateChanageReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
filter.addAction(Intent.ACTION_MEDIA_EJECT);
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addDataScheme("file");
registerReceiver(sdcardStateReceiver, filter);
}

protected void onDestroy() {
unregisterReceiver(sdcardStateReceiver);
}

class SdcardStateChanageReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
checkSDCard();
}

public void checkSDCard() {
String state = Environment.getExternalStorageState();
System.out.println(state);
if (state.equals(Environment.MEDIA_REMOVED) || state.equals(Environment.MEDIA_UNMOUNTED)) {
System.out.println("SDCard 已卸载!");
}
}
}
}

❹ 注册广播有几种方式,这些方式有何优缺点

BroadcastReceiver用于监听被广播的事件
必须被注册,有两种方法:
1、在应用程序的代码中注册
注册BroadcastReceiver:
registerReceiver(receiver,filter);
取消注册BroadcastReceiver:
unregisterReceiver(receiver);
当BroadcastReceiver更新UI,通常会使用这样的方法注册。启动Activity时候注册BroadcastReceiver,Activity不可见时候,取消注册。
2、在androidmanifest.xml当中注册
<receiver>
<intent-filter>
<action android:name = "android.intent.action.PICK"/>
</intent-filter>
</receiver>
1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。
2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

使用这样的方法注册弊端:它会始终处于活动状态,毕竟是手机开发,cpu和电源资源比较少,一直处于活动耗费大,不利。

❺ 注册广播有几种方式,这些方式有何优缺点请谈谈Android引入广播机制的用意。

android中,不同进程之间传递信息要用到广播,可以有两种方式来实现。
第一种方式:在Manifest.xml中注册广播,是一种比较推荐的方法,因为它不需要手动注销广播(如果广播未注销,程序退出时可能会出错)。
具体实现在Manifest的application中添加:

上面两个android:name分别是广播名和广播的动作(这里的动作是表示系统启动完成),如果要自己发送一个广播,在代码中为:
Intent i = new Intent(“android.intent.action.BOOT_COMPLETED”);
sendBroadcast(i);
这样,广播就发出去了,然后是接收。
接收可以新建一个类,继承至BroadcastReceiver,也可以建一个BroadcastReceiver的实例,然后得写onReceive方法,实现如下:
protected BroadcastReceiver mEvtReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(“android.intent.action.BOOT_COMPLETED”)) {
//Do something
}
}
};

第二种方式,直接在代码中实现,但需要手动注册注销,实现如下:
IntentFilter filter = new IntentFilter();
filter.addAction(“android.intent.action.BOOT_COMPLETED”);
registerReceiver(mEvtReceiver, filter); //这时注册了一个recevier ,名为mEvtReceiver,然后同样用上面的方法以重写onReceiver,
最后在程序的onDestroy中要注销广播,实现如下:
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mPlayerEvtReceiver);
}

阅读全文

与android广播缺点相关的资料

热点内容
idea编译进度条 浏览:132
文件夹工具箱软件 浏览:686
最近为什么手机连不上索尼服务器 浏览:877
海康录像机怎么关视频加密 浏览:786
编程以后有可能被机器人代替吗 浏览:522
windows创建文件命令 浏览:986
linuxcopy文件内容 浏览:383
程序员帅哥秃顶 浏览:839
阿里云服务器开通流程 浏览:105
如何开云服务器 浏览:979
网站小说源码 浏览:301
php用什么ide 浏览:867
网上预约课程app哪个好 浏览:152
android兼容测试工具 浏览:96
云服务器不支持虚拟化怎么办 浏览:189
加密方式的演变 浏览:364
java常用算法pdf 浏览:734
服务器数据遇到异常什么原因 浏览:450
phpexif信息 浏览:543
单片机三字节浮点数 浏览:757