android进程间通信之Broadcast

##前言 由于android系统中应用程序之间不能共享内存。因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些。

在android SDK中提供了4种用于跨进程通讯的方式。这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。

  • Activity可以跨进程调用其他应用程序的Activity;
  • Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操 作;
  • Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;
  • Service和Content Provider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,
  • Service返回的是Java对象,这种可以跨进程通讯的服务叫AIDL服务。

##问题 我的同学遇到了两个应用程序进行通讯的问题,下面为解决这个问题所做一下总结。

事情是这样的他们公司有两个不同的应用需要通讯,这里是要用广播方式来实现。 他的广播是在AndroidManifest中静态注册的因为他需要在程序没有运行时做一些事情,同时呢如果应用正在运行时还需要UI做动态的更新,这就是问题了的所在了。 ##解决 开始的问题是在 BroadcastReceiver的 onReceive中根本获取不到UI的对象,平时写BroadcastReceiver都是在Activity中直接写了,就需要传递参数了。

我这里呢是使用接口的形式来实现的。首先定义一个接口,接口中就是广播接收器发送来的内容,这里我们是设置文本。

/**
 * @category XXX广播接收器接口
 * 
 * @author ylbf
 * @version 2016-02-17 17:15:52
 */
public interface BRInteraction {
	/**
	 * 
	 * @param content
	 *            传递内容
	 */
	public void setText(String content);
}

我这里是用插拔USB的方式来来触发对充电状态的广播来模拟别的应用发送的广播。然后把数据通过接口来发送。同时弹出一个Toast来证明应用退出了广播接收器还在工作状态中。

public class PowerConnectionReceiver extends BroadcastReceiver {
	private BRInteraction brInteraction;

	@Override
	public void onReceive(Context context, Intent intent) {

		int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
		boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
		boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
		Toast.makeText(context, "USB充电:" + usbCharge, Toast.LENGTH_SHORT).show();
		if (brInteraction != null) {
			brInteraction.setText("USB充电:" + usbCharge);
		}
	}

	public void setBRInteractionListener(BRInteraction brInteraction) {
		this.brInteraction = brInteraction;
	}
}

下面别忘了在AndroidManifest文件中静态注册

        <receiver android:name=".PowerConnectionReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>

到了这一步这个广播接收器已经完成一半了启动应用会发现这个这个广播接收器可以工作了可以弹出这个Toast来显示充电的状态。 下面是Activity中注册监听器的代码这里呢是改变UI上的一个TextView中的内容。

	/**
	 * 注册监听器
	 * 
	 * @param textView
	 */
	private void regListener(final TextView textView) {
		PowerConnectionReceiver powerConnectionReceiver = new PowerConnectionReceiver();
		powerConnectionReceiver.setBRInteractionListener(new BRInteraction() {

			@Override
			public void setText(String content) {
				if (content != null) {
					textView.setText(content);
				}
			}
		});
	}

启动应用插拔USB之后查看Toast正常弹出但是UI上的TextView并没有改变,经过调试发现Activity调用onReceive方法中brInteraction为NULL ,所以UI上的回掉方法就没有执行。看来这种方法还是不够的。

接着呢下面又在UI界面中又注册了一遍广播接收器发现可以了。

/**
	 * 注册监听器且注册广播
	 * 
	 * @param textView
	 */
	private void regListenerAndReceiver(final TextView textView) {
		IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
		PowerConnectionReceiver powerConnectionReceiver = new PowerConnectionReceiver();
		registerReceiver(powerConnectionReceiver, intentFilter);
		powerConnectionReceiver.setBRInteractionListener(new BRInteraction() {

			@Override
			public void setText(String content) {
				if (content != null) {
					textView.setText(content);
				}
			}
		});
	}

##android广播动态与静态注册小知识 android的广播分为静态注册和动态注册两种方式,具体的操作方式网上有非常多的案例。这里主要记录一下他们的一些特殊的小知识。

1.动态注册和静态注册可以同时进行,简单来说就是使用一个Receiver分别在AndroidManifast中进行注册,又写入在程序中用代码注册(无论Action是否相同),两种注册方式不会造成影响。动态注册只会在程序存在时执行,静态注册一直执行。哪怕是完全相同的Receiver。即如果程序存在,该Receiver会被执行两次。

2.动态注册使用同一个Receiver对象,从开始创建直到其被解除注册。会使用同一个Receiver,无论这个广播被触发几次。而静态注册则每次触发都会建立新的Receiver对象。

3.android.intent.action.SCREEN_ONandroid.intent.action.SCREEN_OFF不可以使用静态注册(没有效果),必须使用动态注册的方式。可能是由于android的内部管理机制导致,不希望程序在未运行时还保持对屏幕的监视。

转载于:https://my.oschina.net/u/2293736/blog/616541

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值