android进程间通讯之Broadcast

##前言 因为android系统中应用程序之间不能共享内存。所以,在不一样应用程序之间交互数据(跨进程通信)就稍微麻烦一些。android

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

  • Activity能够跨进程调用其余应用程序的Activity;
  • Content Provider能够跨进程访问其余应用程序中的数据(以Cursor对象形式返回),固然,也能够对其余应用程序的数据进行增、删、改操 做;
  • Broadcast能够向android系统中全部应用程序发送广播,而须要跨进程通信的应用程序能够监听这些广播;
  • Service和Content Provider相似,也能够访问其余应用程序中的数据,但不一样的是,Content Provider返回的是Cursor对象,
  • Service返回的是Java对象,这种能够跨进程通信的服务叫AIDL服务。

##问题 个人同窗遇到了两个应用程序进行通信的问题,下面为解决这个问题所作一下总结。this

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

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

/**
 * @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界面中又注册了一遍广播接收器发现能够了。get

/**
	 * 注册监听器且注册广播
	 * 
	 * @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的内部管理机制致使,不但愿程序在未运行时还保持对屏幕的监视。

相关文章
相关标签/搜索