标签:
为了方便进行系统级别的消息通知,Android有一套类似广播的消息机制,每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能是来自于系统,也可能是来自于其他程序。
广播可以分为两种类型:有序广播和标准广播
标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因为它们之间没有任何先后顺序可言,这种广播的效率会比较高,但同时也意味着它是无法被截断的
如上图所示,每个人都代表一个广播接收器,在广播发出之后,每个人(广播接收器)都会接收到这条广播
有序广播是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够接收到,当这个广播接收器中的逻辑执行完毕之后,广播才会继续传递。所以有序广播是有先后顺序的,优先级高的广播接收器可以先接受到广播消息,并且还可以阻断正在传递的广播,如果截断,后面的接收器就无法收到了
一个简单的示例演示一下:
MainActivity.java
package cn.lixyz.broadcasttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //创建IntentFilter对象,并指定想要接收的广播 intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); //创建广播接收器,并注册 networkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(networkChangeReceiver, intentFilter); } @Override protected void onDestroy() { super.onDestroy(); //取消注册广播接收器 unregisterReceiver(networkChangeReceiver); } //定义一个广播接收器 class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "网络环境发生变化啦!!", Toast.LENGTH_SHORT).show(); } } }
activity_main.xml默认即可,演示结果,按home键回到桌面(不要back),进入设置,关闭wifi
开启或关闭WIFI都会提示网络环境发生变化了,这里就是APP接收到了系统关闭/开启发出的广播,然后做出的反应。
发送广播只需要调用Context的sendBroadcast(Intent intent)方法即可,这条广播会启动intent参数所对应的BroadcastReceiver。
修改一下上面的代码
MainActivity.java
package cn.lixyz.broadcasttest; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.EditText; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); EditText et = (EditText) findViewById(R.id.editText); String str = et.getText().toString(); intent.setAction("BroadcastReceiver_Test"); intent.putExtra("data", str); sendBroadcast(intent); } }); } }
MyReceiver.java
package cn.lixyz.broadcasttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; /** * Created by LGB on 2015/9/11. */ public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "接收到的消息是: " + intent.getStringExtra("data"), Toast.LENGTH_SHORT).show(); } }
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入您要广播的消息" /> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:text="发送广播" /> </LinearLayout>
AndroidManiFest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.lixyz.broadcasttest"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".MyReceiver"> <intent-filter> <action android:name="BroadcastReceiver_Test" /> </intent-filter> </receiver> </application> </manifest>
运行结果:
从AndroidManiFest中我们可见,MyReceiver监听BroadcastReceiver_Test这个acitivty,当符合该MyReceiver的广播出现时,MyReceiver的onReceiver()将会被触发。
在上面的代码中,使用的是sendBroadcast()方法来发送的广播,android提供了两种方法用于发送广播:
1)sendBroadcast()——用于发送普通广播
2)sendOrderedBroadcast()——用于发送有序广播
对于有序广播而言,系统会根据接受者声明的优先级逐个执行接收器,在接收器接收到广播之后,可以选择继续传递,也可以终止广播,如果终止,那么后面的优先级的接收器就无法再接收到了,在接收到广播之后,接收者可以使用setResultExtras(Bundle)方法来将内容存入到Broadcast中,然后传给下一个接收者,下一个接收者可以通过Bundle bundle = getResultExtras(true)来接收上一个接收器存入的信息
看代码:
MainActivity.java
package cn.lixyz.broadcasttest; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.EditText; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); EditText et = (EditText) findViewById(R.id.editText); String str = et.getText().toString(); intent.putExtra("MainActivity", str); intent.setAction("BroadcastReceiver_Test"); sendOrderedBroadcast(intent, null); } }); } }
MyFirstReceiver.java
package cn.lixyz.broadcasttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; /** * Created by LGB on 2015/9/11. */ public class MyFirstReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String str = intent.getStringExtra("MainActivity"); Bundle bundle = new Bundle(); bundle.putString("MyFirstReceiver", "第一个广播接受者加入的消息"); bundle.putString("MainActivity",intent.getStringExtra("MainActivity")); setResultExtras(bundle); } }
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入您要广播的消息" /> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:text="发送广播" /> </LinearLayout>
AndroidManiFest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.lixyz.broadcasttest"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".MyFirstReceiver"> <intent-filter android:priority="5"> <action android:name="BroadcastReceiver_Test" /> </intent-filter> </receiver> <receiver android:name=".MySecondReceiver"> <intent-filter android:priority="4"> <action android:name="BroadcastReceiver_Test" /> </intent-filter> </receiver> </application> </manifest>
MySecondReceiver.java
package cn.lixyz.broadcasttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.widget.Toast; /** * Created by LGB on 2015/9/11. */ public class MySecondReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = getResultExtras(true); String str1 = bundle.getString("MyFirstReceiver"); String str2 = bundle.getString("MainActivity"); Toast.makeText(context, "接收到的消息是: " + str1 + str2, Toast.LENGTH_SHORT).show(); } }
运行结果
Android笔记(二十六) Android中的广播——BroadcastReceiver
标签:
原文地址:http://www.cnblogs.com/xs104/p/4799779.html