android中什么时候会选择用广播来进行线程间的通信
发布网友
发布时间:2022-04-20 04:54
我来回答
共3个回答
热心网友
时间:2022-04-10 17:36
Android 的广播机制
在 Android
里面有各种各样的广播,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。下面我画一张粗略的图来帮助大家理解广播的运行机制。
Android 中有各式各样的广播,各种广播在Android 系统中运行,当系统/应用程序运行时便会向 Android 注册各种广播,Android
接收到广播会便会判断哪种广播需要哪种事件,然后向不同需要事件的应用程序注册事件,不同的广播可能处理不同的事件也可能处理相同的广播事件,这时就需要 Android
系统为我们做筛选。
案例分析:
一个经典的电话黑名单,首先通过将黑名单号码保存在数据库里面,当来电时,我们接收到来电广播并将黑名单号码与数据库中的某个数据做匹配,如果匹配的话则做出相应的处理,比如挂掉电话、比如静音等等。。。
Demo 分析:
下面通过一个小DEMO 来讲解一下广播在Android
中如何编写,在Demo中我们设置了一个按钮为按钮设置点击监听通过点击发送广播,在后台中接收到广播并打印LOG信息。代码如下:
BroadCastActivity 页面代码
public class BroadCastActivity extends Activity {
public static final String ACTION_INTENT_TEST =
"com.terry.broadcast.test";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.Button01);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(ACTION_INTENT_TEST);
sendBroadcast(intent);
}
});
}
}
接收器代码如下:
public class myBroadCast extends BroadcastReceiver {
public myBroadCast() {
Log.v("BROADCAST_TAG", "myBroadCast");
}
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.v("BROADCAST_TAG", "onReceive");
}
}
Android 广播的生命周期
在上面的接收器中,继承了BroadcastReceiver 并重写了它的onReceive 并构造了一个函数,下面通过图片来一步一步认识
Android 广播的生命周期。当我点击一下按钮,它向Android 发送了一个广播,如下图:
这时我们再点击一下按钮,它还是会再向 Android 系统发送广播,此时日志信息如下:
下面本人画一张图像,描述了Android 中广播的生命周期,其次它并不像Activity 一样复杂,运行原理很简单如下图:
下面来看一下SDK给出的解释:
大意为:如果一个广播处理完onReceive 那么系统将认定此对象将不再是一个活动的对象,也就会finished掉它。
至此,大家应该能明白 Android 的广播生命周期的原理,代码也不用多介绍,很简单的一个发送广播并处理广播的Demo。
Android 如何判断并筛选广播?
前 面说过 Android 的广播有各式各样,那么Android
系统是如何帮我们处理我们需要哪种广播并为我们提供相应的广播服务呢?这里有一点需要大家注意,每实现一个广播接收类必须在我们应用程序中的 manifest
中显式的注明哪一个类需要广播,并为其设置过滤器,如下图:
Tip:action 代表一个要执行的动作,在Andriod 中有很action 比如 ACTION_VIEW,ACTION_EDIT
那么有些人会问了,如果我在一个广播接收器中要处理多个动作呢?那要如何去处理?
在Android 的接收器中onReceive 以经为我们想到的,同样的你必须在Intent-filter
里面注册该动作,可以是系统的广播动作也可以是自己需要的广播,之后你之需要在onReceive
方法中,通过intent.getAction()判断传进来的动作即可做出不同的处理,不同的动作。具体大家可以去尝试测试一下。
小结:
在Android 中如果要发送一个广播必须使用sendBroadCast 向系统发送对其感兴趣的广播接收器中。
使用广播必须要有一个intent 对象必设置其action动作对象
使用广播必须在配置文件中显式的指明该广播对象
每次接收广播都会重新生成一个接收广播的对象
在BroadCast 中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity 或者 Service 去处理
Android广播机制(两种注册方法)
在android下,要想接受广播信息,那么这个广播接收器就得我们自己来实现了,我们可以继承BroadcastReceiver,就可以有一个广播接受器了。有个接受器还不够,我们还得重写BroadcastReceiver里面的onReceiver方法,当来广播的时候我们要干什么,这就要我们自己来实现,不过我们可以搞一个信息防火墙。具体的代码:
public class SmsBroadCastReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
Object[] object = (Object[])bundle.get("ps");
SmsMessage sms[]=new SmsMessage[object.length];
for(int i=0;i
{
sms[0] = SmsMessage.createFromP((byte[])object[i]);
Toast.makeText(context, "来自"+sms[i].getDisplayOriginatingAddress()+"
的消息是:"+sms[i].getDisplayMessageBody(), Toast.LENGTH_SHORT).show();
}
//终止广播,在这里我们可以稍微处理,根据用户输入的号码可以实现短信防火墙。
abortBroadcast();
}
}
当实现了广播接收器,还要设置广播接收器接收广播信息的类型,这里是信息:android.provider.Telephony.SMS_RECEIVED
我们就可以把广播接收器注册到系统里面,可以让系统知道我们有个广播接收器。这里有两种,一种是代码动态注册:
//生成广播处理
smsBroadCastReceiver = new SmsBroadCastReceiver();
//实例化过滤器并设置要过滤的广播
IntentFilter intentFilter = new
IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//注册广播
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver,
intentFilter);
一种是在AndroidManifest.xml中配置广播
package="spl.broadCastReceiver"
android:versionCode="1"
android:versionName="1.0">
android:label="@string/app_name">
两种注册类型的区别是:
1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。
2)第二种是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
BroadcastReceiver用于监听被广播的事件
必须被注册,有两种方法:
1、在应用程序的代码中注册
注册BroadcastReceiver:
registerReceiver(receiver,filter);
取消注册BroadcastReceiver:
unregisterReceiver(receiver);
当BroadcastReceiver更新UI,通常会使用这样的方法注册。启动Activity时候注册BroadcastReceiver,Activity不可见时候,取消注册。
2、在androidmanifest.xml当中注册
使用这样的方法注册弊端:它会始终处于活动状态,毕竟是手机开发,cpu和电源资源比较少,一直处于活动耗费大,不利。
热心网友
时间:2022-04-10 18:54
android中什么时候会选择用广播来进行线程间的通信 Android 多线程 通信
线程中通信就不要用广播了吧 进程中通信可以用广播或者aidl
可是,这两天看到的项目都是这么做的;然后,自己分析了下,觉得一下的理由也是可以成立的;
1.正常情况下我们选择handler消息机制来进行单向的线程间的通信;(工作线程向主线程发送消息)
因为主线程有现成的handler,而工作线程没有现成的handler,这样的话,主线程将handler交给工作线程而让工作线程将工作的结果交给主线程;
相反,工作线程中没有现成的handler(事实上是没有消息队列,也就是handler没有绑定到工作线程),那么,如果开辟的话,代码角度上是挺麻烦的(相对应广播机制来说);
2.广播机制本身就是双向的(工作线程向主线程发送广播,主线程向工作线程发送广播);
//另外,对于像一个activity中通过fragment来进行界面的处理; 我们大多数情况下是采用广播的机制来实现fragment中adapter的数据的更新;这样做主要是考虑到工作线程的任务加载完成,而具体的对应刷新的activity可能还没有启动;
另外,基于接口隔离原则,如果用handler进行通信的话,则不能很好的满足这一原则;
你要是周期比较长 用广播好些吧
应该与周期关系不是很密切。最主要的原因是两条线成是双向通信。
Handler类似于P2P的通信。
广播则类似于一个server端,用来处理分发不同线程的请求,从控制器的角度来说用广播更好一点。
一般使用Handler的,多用于子线程处理事务,完成时告知主线程这一类的情况。
而类似楼主所说的多条线程之间需要频繁交互的话,广播是个很好的选择,并且结构清晰,只是不知道广播的性能与handler相比会怎么样。
热心网友
时间:2022-04-10 20:29
这个名字都给你取的这么好听了。广播:需要向外接广泛传播的数据。适用于1对多方案。党*宣布人民集体戴口罩。就是用的广播!懂了么兄弟