1. 程式人生 > >[心得]Android程序間通訊之Broadcast Receiver

[心得]Android程序間通訊之Broadcast Receiver

Android框架層提供的一些通訊機制BroadcastIntentContent Provider,主要用於應用程式開發時提供跨程序或應用程式內部的通訊。

android中,通過廣播(broadcast)可以通知廣播接受者某個事件發生了。比如一些系統時間:電源不足,時間改變等,也可以是自定義的事件。

有兩種方式可以註冊:靜態註冊(冷註冊動態註冊(熱註冊)。

冷註冊,就是Broadcast Receiver的相關資訊寫在配置檔案中,系統會負責在相關事件發生的時候及時通知到該Broadcast Receiver。這種模式適合於這樣的場景:某事件發生 -> 通知Broadcast -> 

啟動相關處理應用。比如,監聽來電、郵件、簡訊之類的,都隸屬於這種模式。 

熱註冊,顧名思義,註冊這樣的事情都是由應用自己來處理的,通常是在OnResume事件中通過registerReceiver進行註冊,在OnPause等事件中通過unregisterReceiver反註冊,通過這種方式使其能夠在執行期間保持對相關事件的關注。比如,一款優秀的詞典軟體,可能會有在執行期間關注網路狀況變化的需求,使其可以在有廉價網路的時候優先使用網路查詢詞彙,在其他情況下,首先通過本地詞庫來查詞。而這樣的監聽,只需要在其工作狀態下保持就好,不執行的時候,管你是天大的網路變化,與我何干。其模式可以歸結為:啟動應用 

-> 監聽事件 -> 發生時進行處理。 

冷註冊:

       

Activity中:

public class MainActivity extends Activity {
	public static final String NEW_LIFEFROM_DETECTED = "com.android.broadcasttest.BRDEMO1";
	private int count=0;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn=(Button) findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				
				Intent intent=new Intent(NEW_LIFEFROM_DETECTED);
				intent.putExtra("text", String.valueOf(count++));
				sendBroadcast(intent);
			}
		});
  }

繼承一個Broadcast

public class MyBroadReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		Log.i("BROAD", "receive");
		String str=intent.getStringExtra("text");
		Toast.makeText(context, "receive:"+str, Toast.LENGTH_LONG).show();
	}
}

AndroidManifest中註冊:

<receiver android:name=".MyBroadReceiver"
            >
            <intent-filter >
                <action android:name="com.android.broadcasttest.BRDEMO1"/>
            </intent-filter>
        </receiver>


 

熱註冊:

public class MainActivity extends Activity {
	BroadcastReceiver br=null;
	public static final String NEW_LIFEFROM_DETECTED = "com.android.broadcasttest.BRDEMO1";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn =(Button) findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener() {	
			@Override
			public void onClick(View v) {
				Date date=new Date();
				String str=date.toLocaleString();
				Log.i("btn", str);
				Intent intent=new Intent(NEW_LIFEFROM_DETECTED);
				intent.putExtra("demo2", str);
				sendBroadcast(intent);
			}
		});
        br=new BroadcastReceiver() {//在onCreat()中定義
			
			@Override
			public void onReceive(Context context, Intent intent) {
				System.out.println(intent.getStringExtra("demo2"));
			}
		};
    }
    
    @Override
    protected void onResume() {
    	super.onResume();
    	IntentFilter intentf=new IntentFilter();
    	intentf.addAction(NEW_LIFEFROM_DETECTED);
    	//intentf.addAction(Intent.ACTION_TIME_TICK);
    	registerReceiver(br, intentf);//在onResume()中註冊
    }
    @Override
    protected void onPause() {
    	super.onPause();
    	unregisterReceiver(br);//不要忘了在onPause()中登出
    }


測試結果:

從結果可以看到,點選按鈕之後,通過Log.i("btn", str)列印了一行程式碼,然後通過Intent傳到BroadCast中,通過System.out 列印結果

但最後一行又冒出來一句,PID是不同的,這是前一個Demo也接收到了這個事件(相同的標識)。但反過來,在第一個應用中點選send 第二個卻接收不到。如果要讓第一個不接受別的AppBroadCast,應將第一個的AndroidManifest中的receiver標籤新增一個屬性為:

<receiver android:name=".MyBroadReceiver"
            android:exported="false">
            <intent-filter >
                <action android:name="com.android.broadcasttest.BRDEMO1"/>
            </intent-filter>
        </receiver>

如果要第二個APP能夠接收到該Broadcast,那麼要在AndroidManifest中新增uses-permission標籤

需要注意的是,當Broadcast Receiver接收到相關的訊息,在OnReceive中不要執行很消耗時間的操作,通常把消耗時間的操作放到一個Service中,在OnReceive中啟動該Service