在 Android - Intent与IntentFilter 一文的开头,我们提到,一个Intent是对将要被执行的一个操作的一种抽象的描述,结合Context类中定义的下列几个方法 ——

public abstract void startActivity(Intent intent);public abstract void sendBroadcast(Intent intent);public abstract ComponentName startService(Intent service);public abstract boolean bindService(Intent service, ServiceConnection conn, int flags);

Intent被用作一种组件之间进行通信的媒介。
public abstract void startActivity(Intent intent)方法是根据指定的intent开启对应的Activity, public abstract ComponentName startService(Intent service)方法是根据指定的intent开启对应的Service, 那么, public abstract void sendBroadcast(Intent intent)方法呢?
一般来说,Intent主要是用作Activity和Service之间通信的媒介,在Activity(Service)中通过Intent开启一个Service(Activity)。 那么,如果我们需要在应用中根据一个Intent来做某些具体的操作(不一定是开启一个Activity或Service)呢?在Context类中可没有什么方法能满足我们的需要,这种情况下,就可以考虑使用广播接收者了。上文中提到的public abstract void sendBroadcast(Intent intent)方法就是用于发送intent的,广播接收者则用于处理intent。
正如startActivity(Intent intent)和startService(Intent service)这两个方法都需要它们所传递的intent先通过IntentFilter的过滤才能开启对应的Activity和Service一样,广播接收者并不会处理所有通过sendBroadcast(Intent intent)方法发送来的intent,它同样需要先声明自己能处理哪些intent。 本文也按照创建广播接收者--订阅感兴趣的广播intent--发送广播intent--处理广播intent的顺序来写。
一、创建广播接收者 创建一个广播接收者只需要继承BroadcastReceiver,并重写onReceive()方法,如:
public class myBroadcastReceiver  extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stub... ...}}
二、订阅感兴趣的广播Intent 订阅的方法有两种: 第一种:使用代码进行订阅(动态订阅):
public void registerStorageChangeReceiver() {IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_MEDIA_SHARED);filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);filter.addAction(UPDATE_LISTVIEW_STRING);filter.addDataScheme("file");storageChangeReceiver = new StorageChangeReceiver();getActivity().registerReceiver(storageChangeReceiver, filter);}
第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅( 静态订阅):
<receiver android:name=".autotask.AutoTaskReceiver"><intent-filter>    <action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter><intent-filter>    <action android:name="android.intent.action.DATE_CHANGED" /></intent-filter></receiver>
两种订阅方式的区别:

静态订阅广播又叫常驻型广播,当应用程序关闭了,如果有广播intent到来,广播接收者同样能接收到。

动态订阅广播又叫非常驻型广播,当应用程序结束了,广播接收者也就被销毁了。


三、发送广播

发送广播的方法定义在Context类中,主要有:

public abstract void sendBroadcast(Intent intent);public abstract void sendBroadcast(Intent intent, String receiverPermission);public abstract void sendOrderedBroadcast(Intent intent, String receiverPermission);public abstract void sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver,            Handler scheduler, int initialCode, String initialData, Bundle initialExtras);
sendBroadcast()用来发送“普通广播(Normal broadcasts)” sendOrderedBroadcast()用来发送“有序广播(Ordered broadcasts)”。 普通广播(Normal broadcasts)是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播。 有序广播(Ordered broadcasts)则按照接收者声明的优先级别被依次接收。如:A的级别高于B的级别高于C的级别,那么,广播先传给A,再传给B,最后传给C 。 优先级别声明在 intent-filter 元素的 android:priority 属性中,数值越大优先级别越高,取值范围:-1000到1000,优先级别也可以调用IntentFilter对象的setPriority()进行设置。 有序广播的接收者可以终止广播Intent的传播(BroadcastReceiver.abortBroadcast()),广播Intent的传播一旦终止,后面的接收者就无法接收到广播。 另外,有序广播的接收者可以通过setResultExtras(Bundle)方法将数据存放进结果对象,然后将数据传递给下一个接收者,下一个接收者通过代码:Bundle bundle = getResultExtras(true))可以获取上一个接收者存入在结果对象中的数据。如:A得到广播后,可以往它的结果对象中存入数据,当广播传给B时,B可以从A的结果对象中得到A存入的数据。

四、处理广播Intent

每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法,

onReceive() 方法执行完后,BroadcastReceiver 的实例就会被销毁。

当onReceive() 方法在10秒内没有执行完毕,Android会认为该程序无响应。所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR(Application No Response)对话框。

如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成。这里不能使用子线程来解决,因为 BroadcastReceiver 的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。

BroadcastReceiver一旦结束,此时BroadcastReceiver所在的进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死。所以采用子线程来解决是不可靠的。

Android将进程分为6个等级,它们按优先级顺序由高到低依次是:

1.前台进程( FOREGROUND_APP)

2.可视进程(VISIBLE_APP )

3. 次要服务进程(SECONDARY_SERVER )

4.后台进程 (HIDDEN_APP)

5.内容供应节点(CONTENT_PROVIDER)

6.空进程(EMPTY_APP)


所以,Intent是组件(主要是Activity和Service)之间进行通信的媒介。广播接收者通过订阅并处理Intent则是组件(主要是Activity和Service)间进行通信的一种方式。



... ... (未完待续)




更多相关文章

  1. Android监听应用的安装、卸载、覆盖
  2. Android使用Toast显示消息提示框
  3. 【Android】报错IOException: Read-only file system问题解决方
  4. Recycler的一些笔记
  5. 选项卡的使用方法一(Android学习随笔十二)
  6. android 3种定时器的方法
  7. android绘图常用方法归纳
  8. android 的事件分发从源码分析
  9. Android与JS交互的细节问题

随机推荐

  1. 详解Android中的Menu菜单键
  2. google天气预报SAX解析版(只有当天的天气)
  3. Android(安卓)用Intent调用系统中经常被
  4. android如何获取默认的桌面程序
  5. (转载)Android一些不常见的API及一些其他
  6. android 自定义标题栏 titleBar自定义
  7. android动画及用法
  8. Android_framework层Service解析
  9. Android弹出拨号界面和拨打电话实现
  10. [Android(安卓)Studio] FloatingActionBu