您的位置:首页 > 其它

BroadcastReceiver

2016-05-13 12:09 316 查看
转载请标明出处: /article/8809995.html

本文出自【吴孝城的CSDN博客】

关于广播的内容,可以看下官方的介绍:http://developer.android.com/intl/zh-cn/reference/android/content/BroadcastReceiver.html

广播的生命周期只在调用onReceive(Context, Intent)时活跃。

广播分两种

Normal broadcasts:标准广播,无序广播

通过Context.sendBroadcast发送,是完全异步的,所有的接收器以不确定的顺序运行,通常是同时的,这样效率更高,但也意味着接收器不能传递结果,也不能中止广播。

Ordered broadcasts:有序广播

通过Context.sendOrderedBroadcast发送,一次只发送给一个接收器,每个接收器按顺序执行,所以它可以向下一个接收器传递结果,也可以退出广播,不再传递给其他接收器,接收器的运行顺序可以通过android:priority属性控制,如< intent-filter android:priority = “1000” >,级别数值在-1000到1000之间,值越大,优先级越高。相同优先级的接收器会以随机的顺序执行。

注册

我们可以用Context.registerReceiver()在程序中动态注册广播,动态注册的需程序启动后才能接收广播。

也可以通过在AndroidManifest.xml中静态注册,静态注册的可以让程序在未启动的情况下接收广播。

如果在Activity.onResume()里注册了一个receiver,就应该在Activity.onPause()里调用unregisterReceiver()注销它,暂停后将不会收到intents,这将减少不必要的系统开销,不用在Activity.onSaveInstanceState()注销,因为用户回到历史堆栈它将不会被调用。

注意

不要在广播里添加任何逻辑和耗时操作,因为广播不允许开辟线程,当onReceive(Context, Intent)运行时间超过10秒还没有结束时,程序会报错(ANR),广播更多的是用来打开其他组件,如Service,Activity,Notification提示等。

接收广播

接下来来实践一下

创建一个类,继承BroadcastReceiver

在onReceive(Context context, Intent intent)方法里完成广播要做的事。

动态注册

MyReceiver.java

package cn.wuxiaocheng.broadcastreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}

// 在onReceive里完成广播要操作的事,这里弹出一个吐丝
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "网络状态发生改变~", Toast.LENGTH_SHORT).show();
}
}


在MainActivity.java中动态注册

package cn.wuxiaocheng.broadcastreceiver;

import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

MyReceiver myReceiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

myReceiver = new MyReceiver();
// 创建意图过虑器
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
// 注册Receiver
registerReceiver(myReceiver, filter);
}

// 注销广播
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(myReceiver);
}
}


在AndroidManifest.xml里声明

<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true"></receiver>




静态注册

MyReceiver.java

package cn.wuxiaocheng.broadcastreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

private final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";

public MyReceiver() {
}

// 在onReceive里完成广播要操作的事,这里弹出一个吐丝
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_BOOT.equals(intent.getAction()))
Toast.makeText(context, "已开机", Toast.LENGTH_LONG).show();
}
}


在AndroidManifest.xml里声明和添加intent-filter

<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.cation.BOOT_COMPLETED" />
</intent-filter>
</receiver>


发送广播

这里只写一个标准广播扩运行,有序广播的可以自己写一下。或者我有空再来补充

标准广播用:sendBroadcast

有序广播用:sendOrderedBroadcast

先写一个程序,创建一个继承BroadcastReceiver的类,实现onReceive(Context context, Intent intent)方法

MyReceiver.java

package cn.wuxiaocheng.broadcastreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

private final String GET_Broadcast = "cn.wuxiaocheng.MY_BROADCAST";

public MyReceiver() {
}

// 在onReceive里完成广播要操作的事,这里弹出一个吐丝
@Override
public void onReceive(Context context, Intent intent) {
if (GET_Broadcast.equals(intent.getAction()))
// 当收到其他应用程序发送的广播时,会弹出Toast
Toast.makeText(context, "收到广播", Toast.LENGTH_LONG).show();
}
}


在AndroidManifest.xml里声明和添加intent-filter

<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="cn.wuxiaocheng.MY_BROADCAST"/>
</intent-filter>
</receiver>


再写一个程序,用来发送广播

只需要写一行发送代码就行

sendBroadcast(new Intent("cn.wuxiaocheng.MY_BROADCAST"));


写一个按钮,点击发送广播

package cn.wuxiaocheng.testbroadcast;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void send(View v){
sendBroadcast(new Intent("cn.wuxiaocheng.MY_BROADCAST"));
}
}


发送后接收广播的程序应付弹出Toast



LocalBroadcastManager

如果我们不需要跨程序发送广播,可以选用:LocalBroadcastManager

注意:

1.本地广播无法通过静态注册方式来接收,相比起全局广播要高效很多

2.在广播中启动Activity时,需要为intent添加FLAG_ACTIVITY_NEW_TASK,不然会报错,因为需要一个栈来存放新打开的Activity

3.在广播中弹出AlertDialog时需要在AndroidManifest.xml设置对话框的类型为TYPE_SYSTEM_ALERT,不然无法弹出< uses-permission android:name=”android.permission.SYSTEM_ALERT_WINDOW” />

来个小例子



MainActivity.java

package cn.wuxiaocheng.testbroadcast;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {

private LocalBroadcastManager mLcalBroadcastManager;
private BroadcastReceiver mBroadcastReceiver;
private IntentFilter mIntentFilter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mLcalBroadcastManager = LocalBroadcastManager.getInstance(this);

// 初始化广播接收者
mBroadcastReceiver = new MyReceiver();
// 创建意图过虑器
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("cn.wuxiaocheng.LOCAL_BROADCAST");
// 注册Receiver
mLcalBroadcastManager.registerReceiver(mBroadcastReceiver, mIntentFilter);
}

public void send(View v) {
Intent intent = new Intent("cn.wuxiaocheng.LOCAL_BROADCAST");
mLcalBroadcastManager.sendBroadcast(intent);
}

// 注销广播
@Override
protected void onPause() {
super.onPause();
mLcalBroadcastManager.unregisterReceiver(mBroadcastReceiver);
}
}


MyReceiver.java

package cn.wuxiaocheng.testbroadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

private final String GET_Broadcast = "cn.wuxiaocheng.LOCAL_BROADCAST";
public MyReceiver() {
}

@Override
public void onReceive(Context context, Intent intent) {
if (GET_Broadcast.equals(intent.getAction()))
// 当收到其他应用程序发送的广播时,会弹出Toast
Toast.makeText(context, "LocalBroadcastManager", Toast.LENGTH_LONG).show();
}
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="cn.wuxiaocheng.testbroadcast.MainActivity">

<Button
android:onClick="send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送广播" />
</RelativeLayout>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: