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

Android - sendOrderedBroadcast也可以这么用

2015-08-17 13:47 696 查看
作为Android的四大组件之一,Broadcast(广播)分为普通广播和有序广播。但是发送广播的形式却有好几种,如下:

public abstract void sendBroadcast(Intent intent)

public abstract void sendBroadcast(Intent intent, String receiverPermission)

public abstract void sendOrderedBroadcast(Intent intent, String receiverPermission)

public abstract void sendOrderedBroadcast(Intent intent,
String receiverPermission,
BroadcastReceiver resultReceiver,
Handler scheduler,
int initialCode,
String initialData,
Bundle initialExtras)

public abstract void sendStickyBroadcast(Intent intent)

以前用sendBroadcast,sendOrderedBroadcast简单的发送广播,然后接收,然后处理等等。后来有个机会又看到了sendOrderedBroadcast的另一种重载形式(上面第四种方法),希望看看这个函数怎么用。并没有去分析源码,感觉自己目前能力不够。但是给一个demo。

我们知道,启动Activity的方式有两种,startActivity和startActivityForResult,第二种在结束(调用finish()函数)启动的Activity时会传递参数并把值返回给他的parentActivity,在接收到回传的值的时候就可以进行一些处理。那么广播也是传播的,我可不可以发送一条广播,接收方收到后,把处理的一些数据再返回给发送方,发送方再做处理呢?其实可以的,但是原理并非与Activity相同,但是可以说有类似的效果,注意,只是看上去的效果。

首先这是一条有序广播,只有通过sendOrderedBroadcast发送的广播,receiver才能够重新赋值,然后继续传播。

重新赋值的方式:setResultCode / setResultData / setResultExtras

其次使用下面方法:

public abstract void sendOrderedBroadcast(Intent intent,
String receiverPermission,
BroadcastReceiver resultReceiver,
Handler scheduler,
int initialCode,
String initialData,
Bundle initialExtras)

看一下官方API的解释:

Version of
sendBroadcast(Intent)
that allows you to receive data back from the broadcast. This is accomplished by supplying your own BroadcastReceiver when calling, which will be treated as a final
receiver at the end of the broadcast -- its
BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)
method will be called with the result values collected from the other receivers. If you use anresultReceiver with this method, then the broadcast will be
serialized in the same way as calling
sendOrderedBroadcast(Intent, String)
.

参数:

intent
- The Intent to broadcast; all receivers matching this Intent will receive the broadcast.

receiverPermission
- String naming a permissions that a receiver must hold in order to receive your broadcast. If null, no permission is required.

resultReceiver
- Your own BroadcastReceiver to treat as the final receiver of the broadcast.

scheduler
- A custom Handler with which to schedule the resultReceiver callback; if null it will be scheduled in the Context's main thread.

initialCode
- An initial value for the result code. Often Activity.RESULT_OK.

initialData
- An initial value for the result data. Often null.

initialExtras
- An initial value for the result extras. Often null.

本来没想看这个,毕竟英语不好,但是网上没找到关于这个方法的解释。我就简单看一下官方的文档,总结后的意思就是,广播是可以允许你从广播中接收返回的数据的,你自己写的广播接收器将会作为最终的一个接收器来接收信息,如果你使用了该方法,并传递进了resultReceiver,这个接收器就是最终处理的接收器,相当于调用了sendOrederedBroadcast(Intent,String)。

至于参数就好理解了,intent - 要发送的广播;receiverPermission - 发送的广播的权限,如果是null,即认为没有,任何符合条件的接收器都能收到;resultReceiver - 最终处理数据的接收器,也就是自己定义的;scheduler - 自定义的一个handler,来处理resultReceiver的回调,(其实就是设置运行这个接收器的线程),如果为null,默认在主线程;后面三个并不重要,通常情况下一次为:-1,null,null。(Activity.RESULT_OK
即 -1)

现在就可以上代码了:

首先创建一个广播类,继承BroadcastReceiver,实现onReceive方法,如下:

public class TestReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.e("i_broadcast", Thread.currentThread().getName());
String s;
if((s = intent.getStringExtra("main"))!=null){
Log.e("i_broadcast", s);
}else{
Log.e("i_broadcast", "null");
}

Bundle bundle = new Bundle();
bundle.putString("test", "testReceiver");
setResultExtras(bundle);

}

}


在mainActivtiy中也声明一个类继承BroadcastReceiver,如下:

class MyReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
DebugLog("当前线程:"+Thread.currentThread().getName());
Bundle bundle = getResultExtras(true);
String string = bundle.getString("test");
DebugLog("string:"+string);

}

}


注册一个广播接收器:

TestReceiver testReceiver;
testReceiver = new TestReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.fleur.broadcast");
registerReceiver(testReceiver, filter);


发送一条广播:

MyReceiver myReceiver = new MyReceiver();
Intent intent = new Intent("com.fleur.broadcast");
intent.putExtra("main", "this is from mainActivity");
sendOrderedBroadcast(intent, null, myReceiver, null, -1, null, null);


用我们在mainActivity中声明的接收器类作为resultReceiver。

现在运行程序打印log如下:



可以看到数据回传给了MainActivity,并且MyReceiver运行在main Thread里。

如果我不希望MyReceiver运行在主线程,可以开辟一个新线程,如下:

HandlerThread mThread;
Handler mHandler;
mThread = new HandlerThread("mythread");
mThread.start();
mHandler = new Handler(mThread.getLooper());


然后将mHandler传入:

sendOrderedBroadcast(intent, null, myReceiver, mHandler, -1, null, null);


此时运行结果如下:



有序广播自然有序传递,可以依次传递给很多广播接收器后,最后传递给我们传入的广播接收器,做最后的处理。看上去的效果是不是也像切换Activity那样呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: