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的內部管理機制致使,不但願程序在未運行時還保持對屏幕的監視。

相關文章
相關標籤/搜索