一听广播二字,我们第一感觉就会联想到了小时候村里的广播播音,收音机等。对于广播来说,广播发送方 并不在意广播接收方 动作, 接收到广播时如何处理,需要干什么,那是你接受者事。其实,Android 中的广播又何尝不是呢。
Android 中有各式各样的广播,各种广播在Android 系统中运行,当系统/应用程序运行时便会向 Android 注册各种广播,Android 接收到广播会便会判断哪种广播需要哪种事件,然后向不同需要事件的应用程序注册事件,不同的广播可能处理不同的事件也可能处理相同的广播事件,这时就需要 Android 系统为我们做筛选。
无论怎么,既然是广播机制,最最起码的必须要有广播方式者,Android中,广播发送有三种形式,即,sendBroadcast(),sendOrderedBroadcast(),sendStickyBroadcast(),至于这三种的区别google一下遍地都是。此外就是接收端,只有接收了才能做相应的动作,如果没有接收,那么广播就没有什么意义了。而Android广播接收使用了2种方式,它们的是继承了BroadcastReceiver,实现其方法onReceive,在广播被接收之后,接收者就可以在onReceive中做各种各样的处理。
下面是广播机制中的2中接收方式的测试Demo;
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Button android:layout_height="wrap_content" android:text="@string/static_label" android:layout_width="wrap_content" android:id="@+id/button1" /> <Button android:text="@string/dynamic_code" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <TextView android:text="TextView" android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
MainActivity实现了主要广播接收发送的简短方式:
public class MyTestBroadcarsReceiverActivity extends Activity { public static final String CODELOGIN_INTENTFILTER_ACTION = "com.testbroadcastreceiver.TestBroadcastReceiver.CodeLogin"; public static final String LABELLOGIN_INTENTFILTER_ACTION = "com.testbroadcastreceiver.TestBroadcastReceiver.LabelLogin"; public static Context mBase; private Button codeLoginBtn; private Button labelLoginBtn; public TextView broadcastReceiverTV; private TextViewParcel mTextViewParcel; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mBase = this; initComponent(); mTextViewParcel = new TextViewParcel(broadcastReceiverTV); mCodeLogin_BroadcastReceiver = new CodeLogin_BroadcastReceiver(); } @Override protected void onStart() { super.onStart(); mFilter = new IntentFilter(); mFilter.addAction(CODELOGIN_INTENTFILTER_ACTION); if (mCodeLogin_BroadcastReceiver != null && mFilter != null) { mBase.registerReceiver(mCodeLogin_BroadcastReceiver, mFilter); } } @Override protected void onStop() { super.onStop(); if (mCodeLogin_BroadcastReceiver != null) { mBase.unregisterReceiver(mCodeLogin_BroadcastReceiver); } } private void initComponent() { labelLoginBtn = (Button) findViewById(R.id.button1); if (labelLoginBtn != null) { labelLoginBtn.setOnClickListener(LabelLogin_SendBroadcastListener); } codeLoginBtn = (Button) findViewById(R.id.button2); if (codeLoginBtn != null) { codeLoginBtn.setOnClickListener(CodeLogin_SendBroadcastListener); } broadcastReceiverTV = (TextView) findViewById(R.id.textView1); if (broadcastReceiverTV != null) { broadcastReceiverTV.setText("Test BroadcastReceiver"); } } public OnClickListener LabelLogin_SendBroadcastListener = new OnClickListener() { @Override public void onClick(View v) { Log.d("TestBroadcastReceiver", "onClick()"); labelLogin_sendBroadcart(); } }; public OnClickListener CodeLogin_SendBroadcastListener = new OnClickListener() { @Override public void onClick(View v) { codeLogin_sendBroadcart(); } }; private void codeLogin_sendBroadcart() { Intent intent = new Intent(); intent.setAction(CODELOGIN_INTENTFILTER_ACTION); Bundle extras = new Bundle(); String str = mBase.getString(R.string.dynamic_code) + ":\n " + mBase.getString(R.string.dynamic_code_content) + "\n "; String s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; char c[] = s.toCharArray(); for (int i = 0; i < 100; i++) { int randomId = new Random().nextInt(s.length()); str += c[randomId]; } extras.putString("TVText_codeLogin", str); intent.putExtras(extras); mBase.sendBroadcast(intent); } private void labelLogin_sendBroadcart() { Intent intent = new Intent(); intent.setAction(LABELLOGIN_INTENTFILTER_ACTION); Bundle extras = new Bundle(); String str = mBase.getString(R.string.static_label) + ":\n " + mBase.getString(R.string.static_label_content) + "\n "; String s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; char c[] = s.toCharArray(); for (int i = 0; i < 100; i++) { int randomId = new Random().nextInt(s.length()); str += c[randomId]; } extras.putString("TVText_labelLogin", str); extras.putParcelable("TVWidget_labelLogin", mTextViewParcel); intent.putExtras(extras); mBase.sendBroadcast(intent); } private CodeLogin_BroadcastReceiver mCodeLogin_BroadcastReceiver; private IntentFilter mFilter; public class CodeLogin_BroadcastReceiver extends BroadcastReceiver { public CodeLogin_BroadcastReceiver() { Log.d("CodeLogin_BroadcastReceiver", "new CodeLogin_BroadcastReceiver()"); } @Override public void onReceive(Context context, Intent intent) { Log.d("CodeLogin_BroadcastReceiver", "onReceive()"); Bundle extras = intent.getExtras(); if (extras != null && broadcastReceiverTV != null) { String str = extras.getString("TVText_codeLogin"); broadcastReceiverTV.setText(str); } } } }
对于静态注册方式,这里实现了利用Bundle传递对象的方式:
package com.testbroadcastreceiver.br; public class LabelLogin_BroadcastReceiver extends BroadcastReceiver { private TextViewParcel mTextViewParcel; public LabelLogin_BroadcastReceiver() { Log.d("LabelLogin_BroadcastReceiver", "new LabelLogin_BroadcastReceiver()"); } @Override public void onReceive(Context context, Intent intent) { Log.d("LabelLogin_BroadcastReceiver", "onReceive()"); Bundle extras = intent.getExtras(); if (extras != null) { if (intent.hasExtra("TVWidget_labelLogin")) { extras.getParcelable("TVWidget_labelLogin"); mTextViewParcel = extras.getParcelable("TVWidget_labelLogin"); } String str = extras.getString("TVText_labelLogin"); if (mTextViewParcel != null && mTextViewParcel.getBroadcastReceiverTV() != null) mTextViewParcel.getBroadcastReceiverTV().setText(str); } } }
Bundle传递对象的处理方式,注意TextViewParcel中writeValue()和readValue()的写法:
public class BroadcastReceiverTV extends Binder {
public TextView mTextView;
}
package com.testbroadcastreceiver.textviewparcel;
public class TextViewParcel implements Parcelable {
private BroadcastReceiverTV broadcastReceiverTV = new BroadcastReceiverTV();
public TextViewParcel(TextView mTextView) {
broadcastReceiverTV.mTextView = mTextView;
}
public TextViewParcel(Parcel in) {
broadcastReceiverTV = (BroadcastReceiverTV)in.readValue(BroadcastReceiverTV.class
.getClassLoader());
}
public TextView getBroadcastReceiverTV() {
return broadcastReceiverTV.mTextView;
}
public void setBroadcastReceiverTV(TextView broadcastReceiverTV) {
this.broadcastReceiverTV.mTextView = broadcastReceiverTV;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(broadcastReceiverTV);
}
public static final Parcelable.Creator<TextViewParcel> CREATOR = new Creator<TextViewParcel>() {
@Override
public TextViewParcel[] newArray(int size) {
return new TextViewParcel[size];
}
@Override
public TextViewParcel createFromParcel(Parcel source) {
return new TextViewParcel(source);
}
};
}