android广播 有序 无序,Android中的有序和无序广播浅析
BroadcastReceiver所對應的廣播分兩類:無序廣播和有序廣播。
無序廣播即為我們平時經常使用的廣播,其主要是通過public abstract void sendBroadcast (Intent intent)方法進行發送,并通過intent傳遞數據。代碼示例如下:
Intent nonOrderIntent = new Intent();
nonOrderIntent.setAction(ACTION);
sendBroadcast(nonOrderIntent);
無序廣播會被注冊了的相應的感興趣(intent-filter匹配)接收,且順序是無序的。如果發送廣播時有相應的權限要求,BroadCastReceiver如果想要接收此廣播,也需要有相應的權限。
無序廣播的廣播接收者不可以使用setResultData()方法和abortBroadcast()方法,如果使用了會報錯。 但是可以使用getResultData()方法,雖然不報錯,但是獲取到的數據為null。但是在一種特殊情況下,getResultData()方法能取到無序廣播傳遞的數據,下文會說明在什么情況下。
無序廣播不可以被攔截,不可以被終止,不可以被修改,無序廣播任何接收者只要匹配條件都可以接收到,無優先級問題。
如果想通過無序廣播傳遞數據,則可以調用intent.putExtra方法傳遞, 接收者可通過intent.get...接收,不可通過getResultData接收。
有序廣播主要是通過public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)方法進行發送。代碼示例如下:
Intent intent = new Intent();
intent.setAction(ACTION);
sendOrderedBroadcast(intent, null, new Priority2BroadcastReceiver(), null, Activity.RESULT_OK, "MainActivity發送了一個有序廣播", null);
先介紹一下public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)方法
官網api的參數解釋:
Parameters
intent The Intent to broadcast; all receivers matching this Intent will receive the broadcast.
receiverPermission String naming a permissions that a receiver must hold in order to receive your broadcast. If null, no permission is required.
resultReceiver Your own BroadcastReceiver to treat as the final receiver of the broadcast.
scheduler A custom Handler with which to schedule the resultReceiver callback; if null it will be scheduled in the Context's main thread.
initialCode An initial value for the result code. Often Activity.RESULT_OK.
initialData An initial value for the result data. Often null.
initialExtras An initial value for the result extras. Often null.
第一個intent:不多說指定intent,所有廣播接收者的匹配規則
第二個receiverPermission:指定廣播接收器的權限,一般自定義,不常用,可傳null。
第三個resultReceiver:指定一個最終的廣播接收器,相當于finally功能,不論優先級,最后都要接收一次廣播,而這一次收到的廣播為無序廣播(可以在BroadcastReceiver中通過boolean orderedBroadcast = isOrderedBroadcast()方法驗證),但是卻可以通過getResultData等方法取得數據,這就是上面提到的特殊情況。
第四個scheduler:看英文沒怎么看懂什么意思,一般傳null。
第五個initialCode:指定一個code,一般傳Activity.RESULT_OK。
第六個initialData:傳一個字符串數據。對應的在BroadcastReceiver中通過String resultData = getResultData()取得數據;通過setResultData("優先級為3的setResultData的數據")修改數據,將數據傳給下一個優先級較低的BroadcastReceiver;如果在優先級較高的BroadcastReceiver中沒有使用setResultData修改數據,那么優先級較低的接收到的數據還是最原始的數據,即initialData的值。
第七個initialExtras:傳一個Bundle對象,也就是可以傳多種類型的數據。對應的在BroadcastReceiver中通過Bundle bundle = getResultExtras(false)取得Bundle對象,然后再通過bundle的各種get方法取得數據;通過setResultExtras()傳入一個修改過的bundle,將該bundle對象傳給下一個優先級較低的BroadcastReceiver;如果在優先級較高的BroadcastReceiver中沒有使用setResultExtras修改數據,那么優先級較低的接收到的數據還是最原始的bundle對象,即initialExtras的值。
有序廣播所對應的所有的receiver按照在intent-filter中設置的android:priority屬性依次執行,android:priority表示優先級,值越大,其所對應的廣播接收者,越先接收到廣播。在android:priority相同的情況下,如果廣播接收器是通過靜態注冊的,則接收到廣播的順序不確定,如果是動態注冊的,先注冊的將先收到廣播。
有序廣播可以被攔截,�可以在較高優先級的接收器中通過abortBroadcast()攔截廣播,這樣就會導致較低優先級的接收器無法收到廣播了,但是sendOrderedBroadcast第三個參數指定的BroadcastReceiver還是會收到廣播的,而且能獲得數據。
有序廣播可以通過原始intent.putExtra這種方式傳遞數據給BroadcastReceiver,也能通過sendOrderedBroadcast方法的最后2個參數傳遞數據,但是通過第一種方式傳遞的數據無法中途修改,通過第二種方式傳遞的可以通過上面參數說明中的方式進行修改。
具體驗證方式可通過如下代碼驗證以上結論:
MainActivity
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.tbc.hsx.testbroadcast.receiver.Priority2BroadcastReceiver;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String ACTION = "com.tbc.hsx.testbroadcast.MainActivity";
public static final String DATA = "data";
public static final String ORDER_DATA = "order_data";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
findViewById(R.id.send_broadcast_btn).setOnClickListener(this);
findViewById(R.id.send_ordered_broadcast_btn).setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
Handler handler = new Handler() {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
}
};
@Override
public void onClick(View view) {
if (view.getId() == R.id.send_broadcast_btn) {
Intent nonOrderIntent = new Intent();
nonOrderIntent.setAction(ACTION);
sendBroadcast(nonOrderIntent);
} else if (view.getId() == R.id.send_ordered_broadcast_btn) {
Intent intent = new Intent();
intent.putExtra(DATA, "有序廣播通過intent.putExtra傳遞的數據");
intent.setAction(ACTION);
Bundle bundle = new Bundle();
bundle.putString(ORDER_DATA, "有序廣播通過bundle傳遞的數據");
sendOrderedBroadcast(intent, null, new Priority2BroadcastReceiver(), handler, Activity.RESULT_OK, "MainActivity發送了一個有序廣播", bundle);
}
}
}
Priority1BroadcastReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* Created by Doraemon
* Date: 16/4/27
* Time: 16:35
* Summary:優先級為1的廣播接收器
*/
public class Priority1BroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData();//獲取有序廣播的數據
System.out.println("優先級為1的接收到的廣播數據resultData---->" + resultData);
setResultData("優先級為1的setResultData的數據");//修改有序廣播的數據
}
}
Priority2BroadcastReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.tbc.hsx.testbroadcast.MainActivity;
/**
* Created by Doraemon
* Date: 16/4/27
* Time: 16:35
* Summary:
*/
public class Priority2BroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
boolean orderedBroadcast = isOrderedBroadcast();
if (orderedBroadcast) {
System.out.println("優先級為1的接收者接收到的是有序廣播");
} else {
System.out.println("優先級為1的接收者接收到的是無序廣播");
}
Bundle bundle=getResultExtras(false);
if (bundle != null) {
String orderData = bundle.getString(MainActivity.ORDER_DATA);
System.out.println("Priority2BroadcastReceiver-------->" + orderData);
}
String resultData = getResultData();//獲取有序廣播的數據
System.out.println("優先級為2的接收到的廣播數據resultData---->" + resultData);
setResultData("優先級為2的setResultData的數據");//修改有序廣播的數據
}
}
Priority3BroadcastReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.tbc.hsx.testbroadcast.MainActivity;
/**
* Created by Doraemon
* Date: 16/4/27
* Time: 16:32
* Summary:
*/
public class Priority3BroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = getResultExtras(false);
if (bundle != null) {
String orderData = bundle.getString(MainActivity.ORDER_DATA);
System.out.println("Priority3BroadcastReceiver-------->" + orderData);
}
// bundle.putString(MainActivity.ORDER_DATA, "優先級為3的接收者修改了bundle數據");
// setResultExtras(bundle);
boolean orderedBroadcast = isOrderedBroadcast();
if (orderedBroadcast) {
System.out.println("優先級為3的接收者接收到的是有序廣播");
} else {
System.out.println("優先級為3的接收者接收到的是無序廣播");
}
String resultData = getResultData();//獲取有序廣播的數據
System.out.println("優先級為3的接收到的廣播數據resultData---->" + resultData);
setResultData("優先級為3的setResultData的數據");//修改有序廣播的數據
// abortBroadcast();
}
}
AndroidManifest.xml(BroadcastReceiver注冊部分)
總結
以上是生活随笔為你收集整理的android广播 有序 无序,Android中的有序和无序广播浅析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 11.集合之map
- 下一篇: android广播 有序 无序,Andr