关闭

广播机制

139人阅读 评论(0) 收藏 举报
分类:
Android 中的广播主要分为两种类型:标准广播和有序广播、

标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息。他们之间没有任何先后顺序可言。无法被截断。

有序广播则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。广播接收器是有先后顺序的,优先级搞得广播接收器就可以先收到广播消息,还可以截断正在传递的广播。



动态注册监听网络变化
       广播接收器可以自由地对自己感兴趣的广播进行注册,这样广播接收器就能够收到该广播,并在内部处理相应的逻辑。注册广播的方式一般有两种:
动态注册和在AndroidManifest.xml中注册,如何创建一个广播接收器呢?

1.继承自BroadcastReceiver
2.重写父类的onReceive()方法



package com.example.chenac.broadcasttest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {

   
private IntentFilter intentFilter;
   
private  NetworkChangeReceiver newworkChangeReceiver;


   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);
       
//
        intentFilter=new IntentFilter();
//当网络状态发生时,系统发出的正是一条值为
       //android.net.conn.CONNECTIVITY_CHANG的广播,也就是说我们的广播接收器                        //想要监听什么广播,就在这里添加相应的action 就行了
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
    //创建了一个 NetworkChangeReceiver 的实例,然后调用registerReceiver()
方法进行注册,将 NetworkChangeReceiver 的实例和IntentFilter 的实例都传了进去,这样
NetworkChangeReceiver 就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE 的广
播,也就实现了监听网络变化的功能。
        newworkChangeReceiver=new NetworkChangeReceiver();
        registerReceiver(
newworkChangeReceiver,intentFilter);

    }

   
@Override
   
protected  void onDestroy(){
       
super.onDestroy();
        unregisterReceiver(
newworkChangeReceiver);
    }


   
class NetworkChangeReceiver extends BroadcastReceiver{
       
@Override
       
public void onReceive(Context context,Intent intent){
            ConnectivityManager connectivityManager=(ConnectivityManager)getSystemService(Context.
CONNECTIVITY_SERVICE);//getSystemService()方法得到了ConnectivityManager 的
            //   实例,这是一个系统服务类,专门用于管理网络连接的
            Toast. makeText(context,"newwork changes",Toast. LENGTH_SHORT).show();


//
//调用它的 getActiveNetworkInfo()
方法可以得到 NetworkInfo 的实例,接着调用NetworkInfo isAvailable()方法,就可以判断
出当前是否有网络了,最后我们还是通过 Toast 的方式对用户进行提示。
            NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
           
if(networkInfo != null && networkInfo.isAvailable()){
                Toast.
makeText(context,
"network is available",Toast.LENGTH_SHORT).show();
            }

        }
    }
}


注意:
最后要记得,动态注册的广播接收器一定都要取消注册才行,这里我们是在 onDestroy()
方法中通过调用 unregisterReceiver()方法来实现的。

这里有非常重要的一点需要说明, Android 系统为了保证应用程序的安全性做了
规定,如果程序需要访问一些系统的关键性信息,必须在配置文件中声明权限才可以,否则
程序将会直接崩溃, 比如这里查询系统的网络状态就是需要声明权限的。打开
AndroidManifest.xml 文件,在里面加入如下权限就可以查询系统网络状态了:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>





静态注册实现开机启动
动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是
它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在
onCreate()方法中的。那么有没有什么办法可以让程序在未启动的情况下就能接收到广播
呢?这就需要使用静态注册的方式了。

public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
}
}

<receiver android:name= ".BootCompleteReceiver" >
    <
intent-filter >
        <action android :name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter >

</receiver>

<application>标签内出现了一个新的标签 <receiver>,所有静态注册的广播接收器
都是在这里进行注册的。它的用法其实和 <activity>标签非常相似,首先通过 android:name
来指定具体注册哪一个广播接收器,然后在 <intent-filter>标签里加入想要接收的广播就行了,
由于Android 系统启动完成后会发出一条值为 android.intent.action.BOOT_COMPLETED 的广
播,因此我们在这里添加了相应的 action
监听系统开机广播也是需要声明权限的,可以看到,我们使用 <uses-permission>
标签又加入了一条 android.permission.RECEIVE_BOOT_COMPLETED 权限。


发送自定义广播
发送标准广播
     
 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
……
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
……
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.broadcasttest. MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>


 ////////////////////////////////////////

public class MainActivity extends Activity {
……
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.
MY_BROADCAST");
sendBroadcast(intent);
}
});
……
}

发送标准广播和发送有序广播的却别
发送标准广播使用的是:sendBroadcast(intent);
发送有序广播使用的是:sendOrderBroadcast(intent,null);   //第二个参数传入的是权限

如何设定广播接收器的先后顺序呢?当然是在注册的时候进行设定的了,修改
AndroidManifest.xml 中的代码:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
<application
android:allowBackup="true"3
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".MyBroadcastReceiver">
<intent-filter android:priority="100" >
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
</manifest>


如果在 onReceive()方法中调用了abortBroadcast()方法,就表示将这条广播截断,后面的
广播接收器将无法再接收到这条广播。现在重新运行程序,并点击一下 Send Broadcast 按钮,
你会发现, 只有 MyBroadcastReceiver 中的Toast 信息能够弹出, 说明这条广播经过
MyBroadcastReceiver 之后确实是终止传递了。

本地广播

前面我们发送和接收的广播全部都是属于系统全局广播,即发出的广播可以被其他任何
的任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样就很容
易会引起安全性的问题。

主要就是使用了一个 LocalBroadcastManager 来对广播进行管理
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3079次
    • 积分:124
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:2篇
    • 译文:0篇
    • 评论:4条
    文章分类
    文章存档
    最新评论