您的位置:首页 > 移动开发 > Android开发

Android知识总结学习--广播

2018-01-09 19:17 441 查看
BroadcasrReceiver是一个全局监听器,可以非常方便的实现系统不同组件之间的通信。用于接收程序所发出的Broadcast Intent。启动非常的方便。

启动步骤如下:

1.创建需要启动的BroadcastReciever的Intent

2.调用Context的sendBroadcast()或者sendOrderBroadcast()方法来启动指定的BroadcastReciever,当应用程序发出一个Broadcast Intent之后,所有匹配该Intent的监听器都有可能被启动

这里我们需要注意广播这类监听器与我们之前遇到的监听器的区别:

1.广播的监听器是属于系统级别的监听器,它拥有自己的进程,只要存在与之匹配的Intent被广播出来,就会被激发

2.之前见到的各种监听事件,它们是运行在指定程序所在的进程中,当程序退出时,各种监听事件也随之关闭。

具体的用法如下,查看源码如下图 :

广播是个抽象类,我们需要去继承实现这个抽象类,所有的逻辑设置均在PendingResult这个类中,查看此类源码如下

public static class PendingResult {

/* @hide /

public static final int TYPE_COMPONENT = 0;

/* @hide /

public static final int TYPE_REGISTERED = 1;

/* @hide /

public static final int TYPE_UNREGISTERED = 2;

final int mType;

final boolean mOrderedHint;

final boolean mInitialStickyHint;

final IBinder mToken;

final int mSendingUser;

final int mFlags;

int mResultCode;

String mResultData;

Bundle mResultExtras;

boolean mAbortBroadcast;

boolean mFinished;

/* @hide /

public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type,

boolean ordered, boolean sticky, IBinder token, int userId, int flags) {

mResultCode = resultCode;

mResultData = resultData;

mResultExtras = resultExtras;

mType = type;

mOrderedHint = ordered;

mInitialStickyHint = sticky;

mToken = token;

mSendingUser = userId;

mFlags = flags;

}

/**

* Version of {@link BroadcastReceiver#setResultCode(int)

* BroadcastReceiver.setResultCode(int)} for

* asynchronous broadcast handling.

*/

public final void setResultCode(int code) {

checkSynchronousHint();

mResultCode = code;

}

/**

* Version of {@link BroadcastReceiver#getResultCode()

* BroadcastReceiver.getResultCode()} for

* asynchronous broadcast handling.

*/

public final int getResultCode() {

return mResultCode;

}

/**

* Version of {@link BroadcastReceiver#setResultData(String)

* BroadcastReceiver.setResultData(String)} for

* asynchronous broadcast handling.

*/

public final void setResultData(String data) {

checkSynchronousHint();

mResultData = data;

}

/**

* Version of {@link BroadcastReceiver#getResultData()

* BroadcastReceiver.getResultData()} for

* asynchronous broadcast handling.

*/

public final String getResultData() {

return mResultData;

}

/**

* Version of {@link BroadcastReceiver#setResultExtras(Bundle)

* BroadcastReceiver.setResultExtras(Bundle)} for

* asynchronous broadcast handling.

*/

public final void setResultExtras(Bundle extras) {

checkSynchronousHint();

mResultExtras = extras;

}

/**

* Version of {@link BroadcastReceiver#getResultExtras(boolean)

* BroadcastReceiver.getResultExtras(boolean)} for

* asynchronous broadcast handling.

*/

public final Bundle getResultExtras(boolean makeMap) {

Bundle e = mResultExtras;

if (!makeMap) return e;

if (e == null) mResultExtras = e = new Bundle();

return e;

}

/**

* Version of {@link BroadcastReceiver#setResult(int, String, Bundle)

* BroadcastReceiver.setResult(int, String, Bundle)} for

* asynchronous broadcast handling.

*/

public final void setResult(int code, String data, Bundle extras) {

checkSynchronousHint();

mResultCode = code;

mResultData = data;

mResultExtras = extras;

}

/**

* Version of {@link BroadcastReceiver#getAbortBroadcast()

* BroadcastReceiver.getAbortBroadcast()} for

* asynchronous broadcast handling.

*/

public final boolean getAbortBroadcast() {

return mAbortBroadcast;

}

/**

* Version of {@link BroadcastReceiver#abortBroadcast()

* BroadcastReceiver.abortBroadcast()} for

* asynchronous broadcast handling.

*/

public final void abortBroadcast() {

checkSynchronousHint();

mAbortBroadcast = true;

}

/**

* Version of {@link BroadcastReceiver#clearAbortBroadcast()

* BroadcastReceiver.clearAbortBroadcast()} for

* asynchronous broadcast handling.

*/

public final void clearAbortBroadcast() {

mAbortBroadcast = false;

}

/**

* Finish the broadcast. The current result will be sent and the

* next broadcast will proceed.

*/

public final void finish() {

if (mType == TYPE_COMPONENT) {

final IActivityManager mgr = ActivityManager.getService();

if (QueuedWork.hasPendingWork()) {

// If this is a broadcast component, we need to make sure any

// queued work is complete before telling AM we are done, so

// we don’t have our process killed before that. We now know

// there is pending work; put another piece of work at the end

// of the list to finish the broadcast, so we don’t block this

// thread (which may be the main thread) to have it finished.

//

// Note that we don’t need to use QueuedWork.addFinisher() with the

// runnable, since we know the AM is waiting for us until the

// executor gets to it.

QueuedWork.queue(new Runnable() {

@Override public void run() {

if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,

“Finishing broadcast after work to component ” + mToken);

sendFinished(mgr);

}

}, false);

} else {

if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,

“Finishing broadcast to component ” + mToken);

sendFinished(mgr);

}

} else if (mOrderedHint && mType != TYPE_UNREGISTERED) {

if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,

“Finishing broadcast to ” + mToken);

final IActivityManager mgr = ActivityManager.getService();

sendFinished(mgr);

}

}

/* @hide /

public void setExtrasClassLoader(ClassLoader cl) {

if (mResultExtras != null) {

mResultExtras.setClassLoader(cl);

}

}

/* @hide /

public void sendFinished(IActivityManager am) {

synchronized (this) {

if (mFinished) {

throw new IllegalStateException(“Broadcast already finished”);

}

mFinished = true;

try {

if (mResultExtras != null) {

mResultExtras.setAllowFds(false);

}

if (mOrderedHint) {

am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,

mAbortBroadcast, mFlags);

} else {

// This broadcast was sent to a component; it is not ordered,

// but we still need to tell the activity manager we are done.

am.finishReceiver(mToken, 0, null, null, false, mFlags);

}

} catch (RemoteException ex) {

}

}

}

/* @hide /

public int getSendingUserId() {

return mSendingUser;

}

void checkSynchronousHint() {

// Note that we don’t assert when receiving the initial sticky value,

// since that may have come from an ordered broadcast. We’ll catch

// them later when the real broadcast happens again.

if (mOrderedHint || mInitialStickyHint) {

return;

}

RuntimeException e = new RuntimeException(

“BroadcastReceiver trying to return result during a non-ordered broadcast”);

e.fillInStackTrace();

Log.e(“BroadcastReceiver”, e.getMessage(), e);

}

}

这个类中主要做了广播接收相关数据的初始化,以及类型的判断。

我们平常所写的广播都是这种类型的

public class BroadcastText extends BroadcastReceiver{

@Override

public void onReceive(Context context, Intent intent) {

//在这里实现我们自己的业务逻辑

}

}

带上问题,我们接收的指令是在什么时候执行的呢?怎么传递过来的呢?那就需要从发送广播的地方查起,Context的sendBroadcast()或者sendOrderBroadcast()方法来启动指定的BroadcastReciever,我们通过查询这两个方法的源码看起

这个是四个发送广播的抽象类,需要我们自己去实现。但是我们还是没有明白广播的指令在哪里发送出去的,那我们就接着往上面走,找到注册 广播的代码

找到这里我们才知道,广播是通过隐式的启动。注册到系统中,至此我们明白是怎么注册,发送指令,接收指令。

具体的使用如下:

动态注册:

静态注册:

在你想要发送广播的地方这样操作:

接收广播的地方:

public class BroadcastText extends BroadcastReceiver{

@Override

public void onReceive(Context context, Intent intent) {

String receive = intent.getStringExtra(“sxh”);

Log.e(“sxh”,”————>>>>>>>>>” +receive);

}

}

使用就是这么简单。

两种广播注册的区别

1.静态注册的广播,只要app在系统的进程中,就可以随时接收到广播信息。

2.动态注册的广播随着类的生命周期结束而结束,随之也结束广播信息的接收。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android 广播 面试