<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_You Know ,I Can Do it .</title><subtitle type="text">没有比人更高的山，没用比脚更长的路！</subtitle><id>http://feed.cnblogs.com/blog/u/57221/rss</id><updated>2012-05-27T14:54:23Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/57221/rss"/><entry><id>http://www.cnblogs.com/myitm/archive/2012/05/27/2520614.html</id><title type="text">udev的实现原理 （转）</title><summary type="text">相对于linux来说，udev还是一个新事物。然而，尽管它03年才出现，尽管它很低调(J)，但它无疑已经成为linux下不可或缺的组件了。udev是什么？它是如何实现的？最近研究Linux设备管理时，花了一些时间去研究udev的实现。udev是什么？u是指user space，dev是指device，udev是用户空间的设备驱动程序吗？最初我也这样认为，调试内核空间的程序要比调试用户空间的程序复杂得多，内核空间的程序的BUG所引起的后果也严重得多，device driver是内核空间中所占比较最大的代码，如果把这些device driver中硬件无关的代码，从内核空间移动到用户空间，自然是一个</summary><published>2012-05-27T14:54:00Z</published><updated>2012-05-27T14:54:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/05/27/2520614.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/05/27/2520614.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: medium;"&gt;相对于&lt;span style="font-family: 'Times New Roman';"&gt;linux&lt;/span&gt;来说，&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;还是一个新事物。然而，尽管它&lt;span style="font-family: 'Times New Roman';"&gt;03&lt;/span&gt;年才出现，尽管它很低调&lt;span style="font-family: 'Times New Roman';"&gt;(&lt;/span&gt;J&lt;span style="font-family: 'Times New Roman';"&gt;)&lt;/span&gt;，但它无疑已经成为&lt;span style="font-family: 'Times New Roman';"&gt;linux&lt;/span&gt;下不可或缺的组件了。&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;是什么？它是如何实现的？最近研究&lt;span style="font-family: 'Times New Roman';"&gt;Linux&lt;/span&gt;设备管理时，花了一些时间去研究&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;的实现。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;是什么？&lt;span style="font-family: 'Times New Roman';"&gt;u&amp;nbsp;&lt;/span&gt;是指&lt;span style="font-family: 'Times New Roman';"&gt;user space&lt;/span&gt;，&lt;span style="font-family: 'Times New Roman';"&gt;dev&lt;/span&gt;是指&lt;span style="font-family: 'Times New Roman';"&gt;device&lt;/span&gt;，&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;是用户空间的设备驱动程序吗？最初我也这样认为，调试内核空间的程序要比调试用户空间的程序复杂得多，内核空间的程序的&lt;span style="font-family: 'Times New Roman';"&gt;BUG&lt;/span&gt;所引起的后果也严重得多，&lt;span style="font-family: 'Times New Roman';"&gt;device driver&lt;/span&gt;是内核空间中所占比较最大的代码，如果把这些&lt;span style="font-family: 'Times New Roman';"&gt;device driver&lt;/span&gt;中硬件无关的代码，从内核空间移动到用户空间，自然是一个不错的想法。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;但我的想法并不正确，&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;的文档是这样说的，&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;1.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;dynamic replacement for /dev&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;。作为&lt;span style="font-family: 'Times New Roman';"&gt;devfs&lt;/span&gt;的替代者，传统的&lt;span style="font-family: 'Times New Roman';"&gt;devfs&lt;/span&gt;不能动态分配&lt;span style="font-family: 'Times New Roman';"&gt;major&lt;/span&gt;和&lt;span style="font-family: 'Times New Roman';"&gt;minor&lt;/span&gt;的值，而&lt;span style="font-family: 'Times New Roman';"&gt;major&lt;/span&gt;和&lt;span style="font-family: 'Times New Roman';"&gt;minor&lt;/span&gt;非常有限，很快就会用完了。&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;能够像&lt;span style="font-family: 'Times New Roman';"&gt;DHCP&lt;/span&gt;动态分配&lt;span style="font-family: 'Times New Roman';"&gt;IP&lt;/span&gt;地址一样去动态分配&lt;span style="font-family: 'Times New Roman';"&gt;major&lt;/span&gt;和&lt;span style="font-family: 'Times New Roman';"&gt;minor&lt;/span&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;2.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;device naming&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;。提供设备命名持久化的机制。传统设备命名方式不具直观性，像&lt;span style="font-family: 'Times New Roman';"&gt;/dev/hda1&lt;/span&gt;这样的名字肯定没有&lt;span style="font-family: 'Times New Roman';"&gt;boot_disk&lt;/span&gt;这样的名字直观。&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;能够像&lt;span style="font-family: 'Times New Roman';"&gt;DNS&lt;/span&gt;解析域名一样去给设备指定一个有意义的名称。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;3.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;API to access info about current system devices&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;。提供了一组易用的&lt;span style="font-family: 'Times New Roman';"&gt;API&lt;/span&gt;去操作&lt;span style="font-family: 'Times New Roman';"&gt;sysfs&lt;/span&gt;，避免重复实现同样的代码，这没有什么好说的。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;我们知道，用户空间的程序与设备通信的方法，主要有以下几种方式，&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;1.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;通过&lt;span style="font-family: 'Times New Roman';"&gt;ioperm&lt;/span&gt;获取操作&lt;span style="font-family: 'Times New Roman';"&gt;IO&lt;/span&gt;端口的权限，然后用&lt;span style="font-family: 'Times New Roman';"&gt;inb/inw/ inl/ outb/outw/outl&lt;/span&gt;等函数，避开设备驱动程序，直接去操作&lt;span style="font-family: 'Times New Roman';"&gt;IO&lt;/span&gt;端口。（没有用过）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;2.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;用&lt;span style="font-family: 'Times New Roman';"&gt;ioctl&lt;/span&gt;函数去操作&lt;span style="font-family: 'Times New Roman';"&gt;/dev&lt;/span&gt;目录下对应的设备，这是设备驱动程序提供的接口。像键盘、鼠标和触摸屏等输入设备一般都是这样做的。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;3.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;用&lt;span style="font-family: 'Times New Roman';"&gt;write/read/mmap&lt;/span&gt;去操作&lt;span style="font-family: 'Times New Roman';"&gt;/dev&lt;/span&gt;目录下对应的设备，这也是设备驱动程序提供的接口。像&lt;span style="font-family: 'Times New Roman';"&gt;framebuffer&lt;/span&gt;等都是这样做的。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;上面的方法在大多数情况下，都可以正常工作，但是对于热插拨&lt;span style="font-family: 'Times New Roman';"&gt;(hotplug)&lt;/span&gt;的设备，比如像&lt;span style="font-family: 'Times New Roman';"&gt;U&lt;/span&gt;盘，就有点困难了，因为你不知道：什么时候设备插上了，什么时候设备拔掉了。这就是所谓的&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;问题了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;处理&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;传统的方法是，在内核中执行一个称为&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;的程序，相关参数通过环境变量传递过来，再由&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;通知其它关注&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;事件的应用程序。这样做不但效率低下，而且感觉也不那么优雅。新的方法是采用&lt;span style="font-family: 'Times New Roman';"&gt;NETLINK&lt;/span&gt;实现的，这是一种特殊类型的&lt;span style="font-family: 'Times New Roman';"&gt;socket&lt;/span&gt;，专门用于内核空间与用户空间的异步通信。下面的这个简单的例子，可以监听来自内核&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;的事件。&lt;/span&gt;&lt;/p&gt;&lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="568"&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;ctype.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;sys/un.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;sys/ioctl.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;sys/socket.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;linux/types.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;linux/netlink.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#include&amp;nbsp;&amp;lt;errno.h&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;static&amp;nbsp;int&amp;nbsp;init_hotplug_sock(void)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;struct&amp;nbsp;sockaddr_nl&amp;nbsp;snl;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;int&amp;nbsp;buffersize&amp;nbsp;= 16 * 1024 * 1024;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;retval;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;memset(&amp;amp;snl, 0x00,&amp;nbsp;sizeof(struct&amp;nbsp;sockaddr_nl));&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;snl.nl_family = AF_NETLINK;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;snl.nl_pid =&amp;nbsp;getpid();&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;snl.nl_groups = 1;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;hotplug_sock&amp;nbsp;=&amp;nbsp;socket(PF_NETLINK,&amp;nbsp;SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(hotplug_sock&amp;nbsp;== -1) {&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("error getting socket: %s",&amp;nbsp;strerror(errno));&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;-1;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/* set receive buffersize */&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setsockopt(hotplug_sock,&amp;nbsp;SOL_SOCKET, SO_RCVBUFFORCE, &amp;amp;buffersize,&amp;nbsp;sizeof(buffersize));&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retval&amp;nbsp;=&amp;nbsp;bind(hotplug_sock, (struct&amp;nbsp;sockaddr&amp;nbsp;*) &amp;amp;snl,&amp;nbsp;sizeof(struct&amp;nbsp;sockaddr_nl));&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(retval&amp;nbsp;&amp;lt; 0) {&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("bind failed: %s",&amp;nbsp;strerror(errno));&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;close(hotplug_sock);&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hotplug_sock&amp;nbsp;= -1;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;-1;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hotplug_sock;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;#define&amp;nbsp;UEVENT_BUFFER_SIZE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2048&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;int&amp;nbsp;main(int&amp;nbsp;argc,&amp;nbsp;char*&amp;nbsp;argv[])&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&amp;nbsp;hotplug_sock&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=&amp;nbsp;init_hotplug_sock();&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(1)&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;char&amp;nbsp;buf[UEVENT_BUFFER_SIZE*2] = {0};&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;recv(hotplug_sock, &amp;amp;buf,&amp;nbsp;sizeof(buf), 0);&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("%s/n",&amp;nbsp;buf);&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;0;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;编译：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;gcc -g hotplug.c -o hotplug_monitor&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;运行后插&lt;span style="font-family: 'Times New Roman';"&gt;/&lt;/span&gt;拔&lt;span style="font-family: 'Times New Roman';"&gt;U&lt;/span&gt;盘，可以看到：&lt;/span&gt;&lt;/p&gt;&lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="568"&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/usbdev2.2_ep00&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/class/scsi_host/host2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep81&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep02&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep83&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/class/usb_device/usbdev2.2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host2/target2:0:0/2:0:0:0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/class/scsi_disk/2:0:0:0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/block/sda&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/block/sda/sda1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/class/scsi_device/2:0:0:0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;add@/class/scsi_generic/sg0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep81&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep02&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/usbdev2.2_ep83&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/class/scsi_generic/sg0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/class/scsi_device/2:0:0:0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/class/scsi_disk/2:0:0:0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/block/sda/sda1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/block/sda&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host2/target2:0:0/2:0:0:0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/class/scsi_host/host2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/class/usb_device/usbdev2.2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/usbdev2.2_ep00&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;remove@/devices/pci0000:00/0000:00:1d.1/usb2/2-1&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;的主体部分在&lt;span style="font-family: 'Times New Roman';"&gt;udevd.c&lt;/span&gt;文件中，它主要监控来自&lt;span style="font-family: 'Times New Roman';"&gt;4&lt;/span&gt;个文件描述符的事件&lt;span style="font-family: 'Times New Roman';"&gt;/&lt;/span&gt;消息，并做出处理：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;1.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;来自客户端的控制消息。这通常由&lt;span style="font-family: 'Times New Roman';"&gt;udevcontrol&lt;/span&gt;命令通过地址为&lt;span style="font-family: 'Times New Roman';"&gt;/org/kernel/udev/udevd&lt;/span&gt;的本地&lt;span style="font-family: 'Times New Roman';"&gt;socket&lt;/span&gt;，向&lt;span style="font-family: 'Times New Roman';"&gt;udevd&lt;/span&gt;发送的控制消息。其中消息类型有：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;l&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;UDEVD_CTRL_STOP_EXEC_QUEUE&amp;nbsp;&lt;/span&gt;停止处理消息队列。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;l&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;UDEVD_CTRL_START_EXEC_QUEUE&amp;nbsp;&lt;/span&gt;开始处理消息队列。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;l&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;UDEVD_CTRL_SET_LOG_LEVEL&amp;nbsp;&lt;/span&gt;设置&lt;span style="font-family: 'Times New Roman';"&gt;LOG&lt;/span&gt;的级别。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;l&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;UDEVD_CTRL_SET_MAX_CHILDS&amp;nbsp;&lt;/span&gt;设置最大子进程数限制。好像没有用。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;l&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;UDEVD_CTRL_SET_MAX_CHILDS_RUNNING&amp;nbsp;&lt;/span&gt;设置最大运行子进程数限制&lt;span style="font-family: 'Times New Roman';"&gt;(&lt;/span&gt;遍历&lt;span style="font-family: 'Times New Roman';"&gt;proc&lt;/span&gt;目录下所有进程，根据&lt;span style="font-family: 'Times New Roman';"&gt;session&lt;/span&gt;的值判断&lt;span style="font-family: 'Times New Roman';"&gt;)&lt;/span&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;l&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;UDEVD_CTRL_RELOAD_RULES&amp;nbsp;&lt;/span&gt;重新加载配置文件。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;2.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;来自内核的&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;事件。如果有事件来源于&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;，它读取该事件，创建一个&lt;span style="font-family: 'Times New Roman';"&gt;udevd_uevent_msg&lt;/span&gt;对象，记录当前的消息序列号，设置消息的状态为&lt;span style="font-family: 'Times New Roman';"&gt;EVENT_QUEUED,&lt;/span&gt;然后并放入&lt;span style="font-family: 'Times New Roman';"&gt;running_list&lt;/span&gt;和&lt;span style="font-family: 'Times New Roman';"&gt;exec_list&lt;/span&gt;两个队列中，稍后再进行处理。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;3.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;来自&lt;span style="font-family: 'Times New Roman';"&gt;signal handler&lt;/span&gt;中的事件。&lt;span style="font-family: 'Times New Roman';"&gt;signal handler&lt;/span&gt;是异步执行的，即使有&lt;span style="font-family: 'Times New Roman';"&gt;signal&lt;/span&gt;产生，主进程的&lt;span style="font-family: 'Times New Roman';"&gt;select&lt;/span&gt;并不会唤醒，为了唤醒主进程的&lt;span style="font-family: 'Times New Roman';"&gt;select&lt;/span&gt;，它建立了一个管道，在&lt;span style="font-family: 'Times New Roman';"&gt;signal handler&lt;/span&gt;中，向该管道写入长度为&lt;span style="font-family: 'Times New Roman';"&gt;1&lt;/span&gt;个子节的数据，这样就可以唤醒主进程的&lt;span style="font-family: 'Times New Roman';"&gt;select&lt;/span&gt;了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;4.&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;来自配置文件变化的事件。&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;通过文件系统&lt;span style="font-family: 'Times New Roman';"&gt;inotify&lt;/span&gt;功能，监控其配置文件目录&lt;span style="font-family: 'Times New Roman';"&gt;/etc/udev/rules.d&lt;/span&gt;，一旦该目录中文件有变化，它就重新加载配置文件。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;其中最主要的事件，当然是来自内核的&lt;span style="font-family: 'Times New Roman';"&gt;hotplug&lt;/span&gt;事件，如何处理这些事件是&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;的关键。&lt;span style="font-family: 'Times New Roman';"&gt;udev&lt;/span&gt;本身并不知道如何处理这些事件，也没有必要知道，因为它只实现机制，而不实现策略。事件的处理是由配置文件决定的，这些配置文件即所谓的&lt;span style="font-family: 'Times New Roman';"&gt;rule&lt;/span&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;关于&lt;span style="font-family: 'Times New Roman';"&gt;rule&lt;/span&gt;的编写方法可以参考《&lt;span style="font-family: 'Times New Roman';"&gt;writing_udev_rules&lt;/span&gt;》，&lt;span style="font-family: 'Times New Roman';"&gt;udev_rules.c&lt;/span&gt;实现了对规则的解析。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;在规则中，可以让外部应用程序处理某个事件，这有两种方式，一种是直接执行命令，通常是让&lt;span style="font-family: 'Times New Roman';"&gt;modprobe&lt;/span&gt;去加载驱动程序，或者让&lt;span style="font-family: 'Times New Roman';"&gt;mount&lt;/span&gt;去加载分区。另外一种是通过本地&lt;span style="font-family: 'Times New Roman';"&gt;socket&lt;/span&gt;发送消息给某个应用程序。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;在&lt;span style="font-family: 'Times New Roman';"&gt;udevd.c:udev_event_process&lt;/span&gt;函数中，我们可以看到，如果&lt;span style="font-family: 'Times New Roman';"&gt;RUN&lt;/span&gt;参数以&lt;span style="font-family: 'Times New Roman';"&gt;&amp;rdquo;socket:&amp;rdquo;&lt;/span&gt;开头则认为是发到&lt;span style="font-family: 'Times New Roman';"&gt;socket&lt;/span&gt;，否则认为是执行指定的程序。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;下面的规则是执行指定程序：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;60-pcmcia.rules:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RUN+="/sbin/modprobe pcmcia"&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;下面的规则是通过&lt;span style="font-family: 'Times New Roman';"&gt;socket&lt;/span&gt;发送消息：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;90-hal.rules:RUN+="socket:/org/freedesktop/hal/udev_event"&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;hal&lt;/span&gt;正是我们下一步要关心的，接下来我会分析&lt;span style="font-family: 'Times New Roman';"&gt;HAL&lt;/span&gt;的实现原理。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2520614.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/05/27/2520614.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2012/05/25/2518449.html</id><title type="text">I/O端口和I/O内存</title><summary type="text">CPU对外设IO端口物理地址的编址方式有两种：一种是I/O映射方式（I/O－mapped），另一种是内存映射方式（Memory－mapped）.有些体系结构的CPU（如，PowerPC、m68k等）通常只实现一个物理地址空间（RAM）。在这种情况下，外设I/O端口的物理地址就被映射到CPU的单一物理地址空间中，而成为内存的一部分。此时，CPU可以象访问一个内存单元那样访问外设I/O端口，而不需要设立专门的外设I/O指令。这就是所谓的"内存映射方式"（Memory－mapped）。而另外一些体系结构的CPU（典型地如X86）则为外设专门实现了一个单独地地址空间，称为&amp;quo</summary><published>2012-05-25T09:57:00Z</published><updated>2012-05-25T09:57:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/05/25/2518449.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/05/25/2518449.html"/><content type="html">&lt;p&gt;&lt;span&gt;&lt;span&gt;CPU&lt;/span&gt;&lt;span&gt;对外设&lt;/span&gt;&lt;span&gt;IO&lt;/span&gt;&lt;span&gt;端口物理地址的编址方式有两种：一种是&lt;/span&gt;&lt;span&gt;&lt;span&gt;I/O&lt;/span&gt;&lt;span&gt;映射方式（&lt;/span&gt;&lt;span&gt;I/O&lt;/span&gt;&lt;span&gt;－&lt;/span&gt;&lt;span&gt;mapped&lt;/span&gt;&lt;span&gt;）&lt;/span&gt;&lt;/span&gt;&lt;span&gt;，另一种是&lt;span&gt;内存映射方式（&lt;/span&gt;&lt;/span&gt;&lt;span&gt;Memory&lt;/span&gt;&lt;span&gt;&lt;span&gt;－&lt;/span&gt;&lt;span&gt;mapped&lt;/span&gt;&lt;span&gt;）&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;有些体系结构的CPU（如，PowerPC、m68k等）通常只实现一个物理地址空间（RAM）。在这种情况下，外设I/O端口的物理地址就被映射到CPU的&lt;span&gt;单一&lt;/span&gt;物理地址空间中，&lt;span&gt;&lt;span&gt;而成为内存的一部分。&lt;/span&gt;此时，&lt;/span&gt;CPU可以象访问一个内存单元那样访问外设I/O端口，而不需要设立专门的外设I/O指令。这就是所谓的&lt;/span&gt;&lt;span&gt;"内存映射方式"（Memory－mapped）&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;　而另外一些体系结构的&lt;/span&gt;CPU（典型地如X86）则为外设专门实现了一个&lt;span&gt;单独&lt;/span&gt;地地址空间，称为&lt;/span&gt;&lt;span&gt;"I/O地址空间"&lt;/span&gt;&lt;span&gt;或者&lt;/span&gt;&lt;span&gt;"I/O端口空间"&lt;/span&gt;&lt;span&gt;。这是一个与CPU地RAM物理地址空间不同的地址空间，所有外设的I/O端口均在这一空间中进行编址。CPU通过设立专门的I/O指令（如X86的IN和OUT指令）来访问这一空间中的地址单元（也即I/O端口）。这就是所谓的&lt;/span&gt;&lt;span&gt;"I/O映射方式"（I/O－mapped）&lt;/span&gt;&lt;span&gt;。&lt;span&gt;与RAM物理地址空间相比，I/O地址空间通常都比较小，如x86 CPU的I/O空间就只有64KB（0－0xffff）。&lt;/span&gt;这是&lt;/span&gt;&lt;span&gt;"I/O映射方式"&lt;/span&gt;&lt;span&gt;的一个主要缺点。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;Linux将基于&lt;/span&gt;&lt;span&gt;I/O映射方式&lt;/span&gt;&lt;span&gt;的或&lt;/span&gt;&lt;span&gt;内存映射方式&lt;/span&gt;&lt;span&gt;的I/O端口通称为&lt;/span&gt;&lt;span&gt;"I/O区域"（I/O region）&lt;/span&gt;&lt;span&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;===============================================================================&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;1、外设都是通过读写设备上的寄存器来进行的，&lt;span&gt;外设寄存器也称为&lt;/span&gt;&lt;/span&gt;&lt;span&gt;"I/O端口"&lt;/span&gt;&lt;span&gt;，而IO端口有两种编址方式：&lt;/span&gt;&lt;span&gt;独立编址&lt;/span&gt;&lt;span&gt;和&lt;/span&gt;&lt;span&gt;统一编制。&lt;/span&gt;&lt;span&gt;而具体采用哪一种则取决于CPU的体系结构。 如，PowerPC、m68k等采用统一编址，而X86等则采用独立编址。但对于Linux内核而言，它可能用于不同的CPU，所以它必须都要考虑这两种方式，于是它采用一种新的方法，将基于I/O映射方式的或内存映射方式的I/O端口通称为&lt;/span&gt;&lt;span&gt;"I/O区域"（I/O region）&lt;/span&gt;&lt;span&gt;，&lt;span&gt;不论你采用哪种方式，都要先申请IO区域：request_resource()，结束时释放它：release_resource()。&lt;/span&gt;&lt;br /&gt;对于某一既定的系统，它要么是独立编址，也即&lt;/span&gt;&lt;span&gt;"I/O端口"&lt;/span&gt;&lt;span&gt;方式，外设寄存器位于"I/O空间"；要么是统一编制，也即&lt;/span&gt;&lt;span&gt;"I/O内存"&lt;/span&gt;&lt;span&gt;方式，外设寄存器位于"内存空间"（很多外设有自己的内存、缓冲区，外设的寄存器和内存统称"I/O空间"）。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;2、对外设的访问分为IO端口访问和IO内存访问。&lt;br /&gt;访问&lt;/span&gt;&lt;span&gt;IO内存&lt;/span&gt;&lt;span&gt;的流程是：request_mem_region() -&amp;gt; ioremap() -&amp;gt; ioread8()/iowrite8() -&amp;gt; iounmap() -&amp;gt; release_mem_region() 。&lt;br /&gt;访问&lt;/span&gt;&lt;span&gt;IO端口&lt;/span&gt;&lt;span&gt;有&lt;span&gt;2&lt;/span&gt;种途径，I/O映射方式（I/O－mapped）、内存映射方式（Memory－mapped）。前一种途径直接使用intb()/outb()之类的函数来读写IO端口，后一种是（为了达到接口的同一性）先把IO端口映射到IO内存（"内存空间"）：ioport_map()，再使用访问IO内存的函数来访问IO端口。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2518449.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/05/25/2518449.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2012/05/21/2512043.html</id><title type="text">BroadcastReceiver应用详解 （转)</title><summary type="text">转自 ：http://blog.csdn.net/liuhe688/article/details/6955668BroadcastReceiver也就是“广播接收者”的意思，顾名思义，它就是用来接收来自系统和应用中的广播。在Android系统中，广播体现在方方面面，例如当开机完成后系统会产生一条广播，接收到这条广播就能实现开机启动服务的功能；当网络状态改变时系统会产生一条广播，接收到这条广播就能及时地做出提示和保存数据等操作；当电池电量改变时，系统会产生一条广播，接收到这条广播就能在电量低时告知用户及时保存进度，等等。Android中的广播机制设计的非常出色，很多事情原本需要开发者亲自操作的</summary><published>2012-05-21T10:27:00Z</published><updated>2012-05-21T10:27:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/05/21/2512043.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/05/21/2512043.html"/><content type="html">&lt;p&gt;转自 ：&lt;a href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;http://blog.csdn.net/liuhe688/article/details/6955668&lt;/a&gt;&lt;/p&gt;&lt;p&gt;BroadcastReceiver也就是&amp;ldquo;广播接收者&amp;rdquo;的意思，顾名思义，它就是用来接收来自系统和应用中的广播。&lt;/p&gt;&lt;p&gt;在Android系统中，广播体现在方方面面，例如当开机完成后系统会产生一条广播，接收到这条广播就能实现开机启动服务的功能；当网络状态改变时系统会产生一条广播，接收到这条广播就能及时地做出提示和保存数据等操作；当电池电量改变时，系统会产生一条广播，接收到这条广播就能在电量低时告知用户及时保存进度，等等。&lt;/p&gt;&lt;p&gt;Android中的广播机制设计的非常出色，很多事情原本需要开发者亲自操作的，现在只需等待广播告知自己就可以了，大大减少了开发的工作量和开发周期。而作为应用开发者，就需要数练掌握Android系统提供的一个开发利器，那就是BroadcastReceiver。下面我们就对BroadcastReceiver逐一地分析和演练，了解和掌握它的各种功能和用法。&lt;/p&gt;&lt;p&gt;首先，我们来演示一下创建一个BroadcastReceiver，并让这个BroadcastReceiver能够根据我们的需要来运行。&lt;/p&gt;&lt;p&gt;要创建自己的BroadcastReceiver对象，我们需要继承android.content.BroadcastReceiver，并实现其onReceive方法。下面我们就创建一个名为MyReceiver广播接收者：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_1" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=1&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.scott.receiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.BroadcastReceiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Context;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Intent;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.util.Log;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;MyReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"MyReceiver"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;msg&amp;nbsp;=&amp;nbsp;intent.getStringExtra(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;msg);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;在onReceive方法内，我们可以获取随广播而来的Intent中的数据，这非常重要，就像无线电一样，包含很多有用的信息。&lt;/p&gt;&lt;p&gt;在创建完我们的BroadcastReceiver之后，还不能够使它进入工作状态，我们需要为它注册一个指定的广播地址。没有注册广播地址的BroadcastReceiver就像一个缺少选台按钮的收音机，虽然功能俱备，但也无法收到电台的信号。下面我们就来介绍一下如何为BroadcastReceiver注册广播地址。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;静态注册&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;静态注册是在AndroidManifest.xml文件中配置的，我们就来为MyReceiver注册一个广播地址：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_2" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=2&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".MyReceiver"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;action&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.action.MY_BROADCAST"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;category&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;配置了以上信息之后，只要是android.intent.action.MY_BROADCAST这个地址的广播，MyReceiver都能够接收的到。注意，这种方式的注册是常驻型的，也就是说当应用关闭后，如果有广播信息传来，MyReceiver也会被系统调用而自动运行。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;动态注册&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;动态注册需要在代码中动态的指定广播地址并注册，通常我们是在Activity或Service注册一个广播，下面我们就来看一下注册的代码：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_3" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=3&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;MyReceiver&amp;nbsp;receiver&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;MyReceiver();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;IntentFilter&amp;nbsp;filter&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;IntentFilter();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;filter.addAction(&lt;span class="string"&gt;"android.intent.action.MY_BROADCAST"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;registerReceiver(receiver,&amp;nbsp;filter);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;注意，registerReceiver是android.content.ContextWrapper类中的方法，Activity和Service都继承了ContextWrapper，所以可以直接调用。在实际应用中，我们在Activity或Service中注册了一个BroadcastReceiver，当这个Activity或Service被销毁时如果没有解除注册，系统会报一个异常，提示我们是否忘记解除注册了。所以，记得在特定的地方执行解除注册操作：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_4" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=4&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onDestroy()&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;super&lt;/span&gt;&lt;span&gt;.onDestroy();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unregisterReceiver(receiver);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;执行这样行代码就可以解决问题了。注意，这种注册方式与静态注册相反，不是常驻型的，也就是说广播会跟随程序的生命周期。&lt;/p&gt;&lt;p&gt;我们可以根据以上任意一种方法完成注册，当注册完成之后，这个接收者就可以正常工作了。我们可以用以下方式向其发送一条广播：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_5" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=5&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;send(View&amp;nbsp;view)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Intent&amp;nbsp;intent&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;Intent(&lt;/span&gt;&lt;span class="string"&gt;"android.intent.action.MY_BROADCAST"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;intent.putExtra(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"hello&amp;nbsp;receiver."&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sendBroadcast(intent);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;注意，sendBroadcast也是android.content.ContextWrapper类中的方法，它可以将一个指定地址和参数信息的Intent对象以广播的形式发送出去。&lt;/p&gt;&lt;p&gt;点击发送按钮，执行send方法，控制台打印如下：&lt;/p&gt;&lt;p&gt;&lt;img src="http://hi.csdn.net/attachment/201111/10/0_13209080389QEC.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;看到这样的打印信息，表明我们的广播已经发出去了，并且被MyReceiver准确无误的接收到了。&lt;/p&gt;&lt;p&gt;上面的例子只是一个接收者来接收广播，如果有多个接收者都注册了相同的广播地址，又会是什么情况呢，能同时接收到同一条广播吗，相互之间会不会有干扰呢？这就涉及到普通广播和有序广播的概念了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;普通广播（Normal Broadcast）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;普通广播对于多个接收者来说是完全异步的，通常每个接收者都无需等待即可以接收到广播，接收者相互之间不会有影响。对于这种广播，接收者无法终止广播，即无法阻止其他接收者的接收动作。&lt;/p&gt;&lt;p&gt;为了验证以上论断，我们新建三个BroadcastReceiver，演示一下这个过程，FirstReceiver、SecondReceiver和ThirdReceiver的代码如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_6" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=6&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.scott.receiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.BroadcastReceiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Context;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Intent;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.util.Log;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;FirstReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"NormalBroadcast"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;msg&amp;nbsp;=&amp;nbsp;intent.getStringExtra(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"FirstReceiver:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;msg);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_7" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=7&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;SecondReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"NormalBroadcast"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;msg&amp;nbsp;=&amp;nbsp;intent.getStringExtra(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"SecondReceiver:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;msg);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_8" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=8&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;ThirdReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"NormalBroadcast"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;msg&amp;nbsp;=&amp;nbsp;intent.getStringExtra(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"ThirdReceiver:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;msg);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;然后再次点击发送按钮，发送一条广播，控制台打印如下：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://hi.csdn.net/attachment/201111/10/0_13209098830caO.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;看来这三个接收者都接收到这条广播了，我们稍微修改一下三个接收者，在onReceive方法的最后一行添加以下代码，试图终止广播：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_9" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=9&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;abortBroadcast();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;再次点击发送按钮，我们会发现，控制台中三个接收者仍然都打印了自己的日志，表明接收者并不能终止广播。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;有序广播（Ordered Broadcast）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有序广播比较特殊，它每次只发送到优先级较高的接收者那里，然后由优先级高的接受者再传播到优先级低的接收者那里，优先级高的接收者有能力终止这个广播。&lt;/p&gt;&lt;p&gt;为了演示有序广播的流程，我们修改一下上面三个接收者的代码，如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_10" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=10&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.scott.receiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.BroadcastReceiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Context;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Intent;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.os.Bundle;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.util.Log;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;FirstReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"OrderedBroadcast"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;msg&amp;nbsp;=&amp;nbsp;intent.getStringExtra(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"FirstReceiver:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;msg);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Bundle&amp;nbsp;bundle&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;Bundle();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bundle.putString(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;msg&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"@FirstReceiver"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setResultExtras(bundle);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_11" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=11&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;SecondReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"OrderedBroadcast"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;msg&amp;nbsp;=&amp;nbsp;getResultExtras(&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;).getString(&lt;/span&gt;&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"SecondReceiver:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;msg);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Bundle&amp;nbsp;bundle&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;Bundle();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bundle.putString(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;msg&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"@SecondReceiver"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setResultExtras(bundle);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_12" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=12&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;ThirdReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"OrderedBroadcast"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String&amp;nbsp;msg&amp;nbsp;=&amp;nbsp;getResultExtras(&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;).getString(&lt;/span&gt;&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"ThirdReceiver:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;msg);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;我们注意到，在FirstReceiver和SecondReceiver中最后都使用了setResultExtras方法将一个Bundle对象设置为结果集对象，传递到下一个接收者那里，这样以来，优先级低的接收者可以用getResultExtras获取到最新的经过处理的信息集合。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;代码改完之后，我们需要为三个接收者注册广播地址，我们修改一下AndroidMainfest.xml文件：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_13" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=13&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".FirstReceiver"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:priority&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"1000"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;action&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.action.MY_BROADCAST"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;category&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".SecondReceiver"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:priority&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"999"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;action&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.action.MY_BROADCAST"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;category&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".ThirdReceiver"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:priority&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"998"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;action&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.action.MY_BROADCAST"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;category&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;我们看到，现在这三个接收者的&amp;lt;intent-filter&amp;gt;多了一个android:priority属性，并且依次减小。这个属性的范围在-1000到1000，数值越大，优先级越高。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;现在，我们需要修改一下发送广播的代码，如下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_14" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=14&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;send(View&amp;nbsp;view)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Intent&amp;nbsp;intent&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;Intent(&lt;/span&gt;&lt;span class="string"&gt;"android.intent.action.MY_BROADCAST"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;intent.putExtra(&lt;span class="string"&gt;"msg"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"hello&amp;nbsp;receiver."&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sendOrderedBroadcast(intent,&amp;nbsp;&lt;span class="string"&gt;"scott.permission.MY_BROADCAST_PERMISSION"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;注意，使用sendOrderedBroadcast方法发送有序广播时，需要一个权限参数，如果为null则表示不要求接收者声明指定的权限，如果不为null，则表示接收者若要接收此广播，需声明指定权限。这样做是从安全角度考虑的，例如系统的短信就是有序广播的形式，一个应用可能是具有拦截垃圾短信的功能，当短信到来时它可以先接受到短信广播，必要时终止广播传递，这样的软件就必须声明接收短信的权限。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;所以我们在AndroidMainfest.xml中定义一个权限：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_15" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=15&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;permission&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:protectionLevel&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"normal"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"scott.permission.MY_BROADCAST_PERMISSION"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;然后声明使用了此权限：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_16" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=16&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;uses-permission&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"scott.permission.MY_BROADCAST_PERMISSION"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;关于这部分如果有不明白的地方可以参考我之前写过的一篇文章：&lt;a title="Android声明和使用权限" href="http://blog.csdn.net/liuhe688/article/details/6417983" target="_blank"&gt;Android声明和使用权限&lt;/a&gt;&lt;/p&gt;&lt;p&gt;然后我们点击发送按钮发送一条广播，控制台打印如下：&lt;/p&gt;&lt;p&gt;&lt;img src="http://hi.csdn.net/attachment/201111/10/0_1320913997FkKj.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;我们看到接收是按照顺序的，第一个和第二个都在结果集中加入了自己的标记，并且向优先级低的接收者传递下去。&lt;/p&gt;&lt;p&gt;既然是顺序传递，试着终止这种传递，看一看效果如何，我们修改FirstReceiver的代码，在onReceive的最后一行添加以下代码：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_17" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=17&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;abortBroadcast();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;然后再次运行程序，控制台打印如下：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://hi.csdn.net/attachment/201111/10/0_1320914377lOyl.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;此次，只有第一个接收者执行了，其它两个都没能执行，因为广播被第一个接收者终止了。&lt;/p&gt;&lt;p&gt;上面就是BroadcastReceiver的介绍，下面我将会举几个常见的例子加深一下大家对广播的理解和应用：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1.开机启动服务&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;我们经常会有这样的应用场合，比如消息推送服务，需要实现开机启动的功能。要实现这个功能，我们就可以订阅系统&amp;ldquo;启动完成&amp;rdquo;这条广播，接收到这条广播后我们就可以启动自己的服务了。我们来看一下BootCompleteReceiver和MsgPushService的具体实现：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_18" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=18&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.scott.receiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.BroadcastReceiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Context;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Intent;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.util.Log;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;BootCompleteReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"BootCompleteReceiver"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Intent&amp;nbsp;service&amp;nbsp;=&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;Intent(context,&amp;nbsp;MsgPushService.&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;context.startService(service);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"Boot&amp;nbsp;Complete.&amp;nbsp;Starting&amp;nbsp;MsgPushService..."&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_19" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=19&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.scott.receiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.app.Service;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Intent;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.os.IBinder;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.util.Log;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;MsgPushService&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;Service&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"MsgPushService"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onCreate()&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;super&lt;/span&gt;&lt;span&gt;.onCreate();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"onCreate&amp;nbsp;called."&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;onStartCommand(Intent&amp;nbsp;intent,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;flags,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;startId)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"onStartCommand&amp;nbsp;called."&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;super&lt;/span&gt;&lt;span&gt;.onStartCommand(intent,&amp;nbsp;flags,&amp;nbsp;startId);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;IBinder&amp;nbsp;onBind(Intent&amp;nbsp;arg0)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;然后我们需要在AndroidManifest.xml中配置相关信息：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_20" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=20&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comments"&gt;&amp;lt;!--&amp;nbsp;开机广播接受者&amp;nbsp;--&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".BootCompleteReceiver"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comments"&gt;&amp;lt;!--&amp;nbsp;注册开机广播地址--&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;action&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.action.BOOT_COMPLETED"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;category&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comments"&gt;&amp;lt;!--&amp;nbsp;消息推送服务&amp;nbsp;--&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;service&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".MsgPushService"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;我们看到BootCompleteReceiver注册了&amp;ldquo;android.intent.action.BOOT_COMPLETED&amp;rdquo;这个开机广播地址，从安全角度考虑，系统要求必须声明接收开机启动广播的权限，于是我们再声明使用下面的权限：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_21" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=21&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;uses-permission&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.permission.RECEIVE_BOOT_COMPLETED"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;经过上面的几个步骤之后，我们就完成了开机启动的功能，将应用运行在模拟器上，然后重启模拟器，控制台打印如下：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://hi.csdn.net/attachment/201111/11/0_1320971403u3G5.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://hi.csdn.net/attachment/201111/11/0_1320971416MKgc.gif" alt="" /&gt;&lt;/p&gt;&lt;p&gt;如果我们查看已运行的服务就会发现，MsgPushService已经运行起来了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2.网络状态变化&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在某些场合，比如用户浏览网络信息时，网络突然断开，我们要及时地提醒用户网络已断开。要实现这个功能，我们可以接收网络状态改变这样一条广播，当由连接状态变为断开状态时，系统就会发送一条广播，我们接收到之后，再通过网络的状态做出相应的操作。下面就来实现一下这个功能：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_22" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=22&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.scott.receiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.BroadcastReceiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Context;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Intent;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.net.ConnectivityManager;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.net.NetworkInfo;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.util.Log;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.widget.Toast;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;NetworkStateReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"NetworkStateReceiver"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"network&amp;nbsp;state&amp;nbsp;changed."&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(!isNetworkAvailable(context))&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Toast.makeText(context,&amp;nbsp;&lt;span class="string"&gt;"network&amp;nbsp;disconnected!"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;).show();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;/**&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="comment"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;网络是否可用&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="comment"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;@param&amp;nbsp;context&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;@return&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="comment"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;boolean&lt;/span&gt;&lt;span&gt;&amp;nbsp;isNetworkAvailable(Context&amp;nbsp;context)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ConnectivityManager&amp;nbsp;mgr&amp;nbsp;=&amp;nbsp;(ConnectivityManager)&amp;nbsp;context.getSystemService(Context.CONNECTIVITY_SERVICE);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NetworkInfo[]&amp;nbsp;info&amp;nbsp;=&amp;nbsp;mgr.getAllNetworkInfo();&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(info&amp;nbsp;!=&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;for&lt;/span&gt;&lt;span&gt;&amp;nbsp;(&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;i&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;info.length;&amp;nbsp;i++)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(info[i].getState()&amp;nbsp;==&amp;nbsp;NetworkInfo.State.CONNECTED)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;再注册一下这个接收者的信息：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_23" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=23&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".NetworkStateReceiver"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;action&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.net.conn.CONNECTIVITY_CHANGE"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;category&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;因为在isNetworkAvailable方法中我们使用到了网络状态相关的API，所以需要声明相关的权限才行，下面就是对应的权限声明：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_24" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=24&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;uses-permission&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.permission.ACCESS_NETWORK_STATE"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;我们可以测试一下，比如关闭WiFi，看看有什么效果。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3.电量变化&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果我们阅读软件，可能是全屏阅读，这个时候用户就看不到剩余的电量，我们就可以为他们提供电量的信息。要想做到这一点，我们需要接收一条电量变化的广播，然后获取百分比信息，这听上去挺简单的，我们就来实现以下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_25" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=25&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;package&lt;/span&gt;&lt;span&gt;&amp;nbsp;com.scott.receiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.BroadcastReceiver;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Context;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.content.Intent;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.os.BatteryManager;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;import&lt;/span&gt;&lt;span&gt;&amp;nbsp;android.util.Log;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;BatteryChangedReceiver&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;extends&lt;/span&gt;&lt;span&gt;&amp;nbsp;BroadcastReceiver&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;final&lt;/span&gt;&lt;span&gt;&amp;nbsp;String&amp;nbsp;TAG&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"BatteryChangedReceiver"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="annotation"&gt;@Override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;onReceive(Context&amp;nbsp;context,&amp;nbsp;Intent&amp;nbsp;intent)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;currLevel&amp;nbsp;=&amp;nbsp;intent.getIntExtra(BatteryManager.EXTRA_LEVEL,&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="comment"&gt;//当前电量&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;intent.getIntExtra(BatteryManager.EXTRA_SCALE,&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="comment"&gt;//总电量&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;percent&amp;nbsp;=&amp;nbsp;currLevel&amp;nbsp;*&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;100&lt;/span&gt;&lt;span&gt;&amp;nbsp;/&amp;nbsp;total;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.i(TAG,&amp;nbsp;&lt;span class="string"&gt;"battery:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;percent&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"%"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;然后再注册一下广播接地址信息就可以了：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_html"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[html]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_26" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=26&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;".BatteryChangedReceiver"&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;action&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.action.BATTERY_CHANGED"&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag-name"&gt;category&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="attribute"&gt;android:name&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span class="attribute-value"&gt;"android.intent.category.DEFAULT"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="tag"&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;intent-filter&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="tag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag-name"&gt;receiver&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;当然，有些时候我们是要立即获取电量的，而不是等电量变化的广播，比如当阅读软件打开时立即显示出电池电量。我们可以按以下方式获取：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_java"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[java]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/liuhe688/article/details/6955668"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_27" width="17" height="17" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=27&amp;amp;width=17&amp;amp;height=17" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;Intent&amp;nbsp;batteryIntent&amp;nbsp;=&amp;nbsp;getApplicationContext().registerReceiver(&lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;IntentFilter(Intent.ACTION_BATTERY_CHANGED));&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;currLevel&amp;nbsp;=&amp;nbsp;batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL,&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE,&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;percent&amp;nbsp;=&amp;nbsp;currLevel&amp;nbsp;*&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;100&lt;/span&gt;&lt;span&gt;&amp;nbsp;/&amp;nbsp;total;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Log.i(&lt;span class="string"&gt;"battery"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"battery:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;percent&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"%"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2512043.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/05/21/2512043.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2012/05/18/2507844.html</id><title type="text">android 获取路径目录方法以及判断目录是否存在，创建目录 （转）</title><summary type="text">Environment 常用方法：* 方法：getDataDirectory()解释：返回 File ，获取 Android 数据目录。* 方法：getDownloadCacheDirectory()解释：返回 File ，获取 Android 下载/缓存内容目录。* 方法：getExternalStorageDirectory()解释：返回 File ，获取外部存储目录即 SDCard* 方法：getExternalStoragePublicDirectory(String type)解释：返回 File ，取一个高端的公用的外部存储器目录来摆放某些类型的文件* 方法：getExternal</summary><published>2012-05-18T07:24:00Z</published><updated>2012-05-18T07:24:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/05/18/2507844.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/05/18/2507844.html"/><content type="html">&lt;p&gt;&lt;span&gt;Environment 常用方法：&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;* 方法：getDataDirectory()&lt;/span&gt;&lt;br /&gt;&lt;span&gt;解释：返回 File ，获取 Android 数据目录。&lt;/span&gt;&lt;br /&gt;&lt;span&gt;* 方法：getDownloadCacheDirectory()&lt;/span&gt;&lt;br /&gt;&lt;span&gt;解释：返回 File ，获取 Android 下载/缓存内容目录。&lt;/span&gt;&lt;br /&gt;&lt;span&gt;* 方法：getExternalStorageDirectory()&lt;/span&gt;&lt;br /&gt;&lt;span&gt;解释：返回 File ，获取外部存储目录即 SDCard&lt;/span&gt;&lt;br /&gt;&lt;span&gt;* 方法：getExternalStoragePublicDirectory(String type)&lt;/span&gt;&lt;br /&gt;&lt;span&gt;解释：返回 File ，取一个高端的公用的外部存储器目录来摆放某些类型的文件&lt;/span&gt;&lt;br /&gt;&lt;span&gt;* 方法：getExternalStorageState()&lt;/span&gt;&lt;br /&gt;&lt;span&gt;解释：返回 File ，获取外部存储设备的当前状态&lt;/span&gt;&lt;br /&gt;&lt;span&gt;* 方法：getRootDirectory()&lt;/span&gt;&lt;br /&gt;&lt;span&gt;解释：返回 File ，获取 Android 的根目录&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;public void getSDPath(){&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;File sdDir = null;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;File sdDir1 = null;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;File sdDir2 = null;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;boolean sdCardExist = Environment.getExternalStorageState()&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;.equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;if (sdCardExist)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;{&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sdDir = Environment.getExternalStorageDirectory();//获取跟目录&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sdDir1 = Environment.getDataDirectory();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;sdDir2 =Environment.getRootDirectory();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;System.out.println("getExternalStorageDirectory(): "+sdDir.toString());&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;System.out.println("getDataDirectory(): "+sdDir1.toString());&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;System.out.println("getRootDirectory(): "+sdDir2.toString());&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;//判断一个路径下的文件（文件夹）是否存在&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;public class IsExist {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;isExist("e://12");&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;/**&lt;/span&gt;&lt;br /&gt;&lt;span&gt;*&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;* @param path 文件夹路径&lt;/span&gt;&lt;br /&gt;&lt;span&gt;*/&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public static void isExist(String path) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;File file = new File(path);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;//判断文件夹是否存在,如果不存在则创建文件夹&lt;/span&gt;&lt;br /&gt;&lt;span&gt;if (!file.exists()) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;file.mkdir();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;1.在SD卡上创建一个文件夹&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public class make extends Activity {&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;/** Called when the activity is first created. */&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;@Override&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public void onCreate(Bundle savedInstanceState) {&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;super.onCreate(savedInstanceState);&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;setContentView(R.layout.main);&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;File sd=Environment.getExternalStorageDirectory();&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;String path=sd.getPath()+"/notes";&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;File file=new File(path);&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;if(!file.exists())&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;file.mkdir();&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2507844.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/05/18/2507844.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2012/05/17/2506635.html</id><title type="text">PackageInstaller 原理简述 &amp;amp; PackageManagerService注记 &amp;amp; PackageParser和AndroidManifest.xml注记 （转）</title><summary type="text">PackageInstaller 原理简述应用安装是智能机的主要特点，即用户可以把各种应用（如游戏等）安装到手机上，并可以对其进行卸载等管理操作。APK是Android Package的缩写，即Android安装包。APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。Android应用安装有如下四种方式1. 系统应用安装――开机时完成，没有安装界面2. 网络下载应用安装――通过market应用完成，没有安装界面3. ADB工具安装――没有安装界面。4. 第三方应用安装――通过SD卡里的APK文件安装，有安装界面</summary><published>2012-05-17T09:55:00Z</published><updated>2012-05-17T09:55:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/05/17/2506635.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/05/17/2506635.html"/><content type="html">&lt;p&gt;PackageInstaller 原理简述&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;应用安装是智能机的主要特点，即用户可以把各种应用（如游戏等）安装到手机上，并可以对其进行卸载等管理操作。APK是Android Package的缩写，即Android安装包。APK是类似Symbian Sis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。&lt;/p&gt;&lt;p&gt;Android应用安装有如下四种方式&lt;br /&gt;1. 系统应用安装――开机时完成，没有安装界面&lt;br /&gt;2. 网络下载应用安装――通过market应用完成，没有安装界面&lt;br /&gt;3. ADB工具安装――没有安装界面。&lt;br /&gt;4. 第三方应用安装――通过SD卡里的APK文件安装，有安装界面，由packageinstaller.apk应用处理安装及卸载过程的界面。&lt;br /&gt;应用安装的流程及路径&lt;br /&gt;应用安装涉及到如下几个目录：&lt;br /&gt;system/app 系统自带的应用程序，无法删除&lt;br /&gt;data/app 用户程序安装的目录，有删除权限。&lt;br /&gt;安装时把apk文件复制到此目录&lt;br /&gt;data/data 存放应用程序的数据&lt;br /&gt;Data/dalvik-cache 将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)&lt;/p&gt;&lt;p&gt;安装过程：复制APK安装包到data/app目录下，解压并扫描安装包，把dex文件(Dalvik字节码)保存到dalvik-cache目录，并data/data目录下创建对应的应用数据目录。&lt;br /&gt;卸载过程：删除安装过程中在上述三个目录下创建的文件及目录。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一、系统应用安装：&lt;br /&gt;PackageManager Service处理各种应用的安装，卸载，管理等工作，开机时由systemServer启动此服务&lt;br /&gt;(源文件路径：android/frameworks/base/services/java/com/android/server/ PackageManagerService.java)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;PackageManager Service服务启动的流程：&lt;br /&gt;1. 首先扫描安装&amp;ldquo;system/framework&amp;rdquo;目录下的jar包&lt;br /&gt;1. scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM,&lt;br /&gt;&amp;nbsp; scanMode | SCAN_NO_DEX);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;2.第二步扫描安装&amp;ldquo;system/app&amp;rdquo;目录下的各个系统应用&lt;br /&gt;scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM, scanMode);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;3.第三步扫描&amp;ldquo;data/app&amp;rdquo;目录，即用户安装的第三方应用&lt;br /&gt;scanDirLI(mAppInstallDir, 0, scanMode);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;4.第四步扫描" data/app-private"目录，即安装DRM保护的APK文件（目前没有遇到过此类的应用）。&lt;br /&gt;scanDirLI(mDrmAppPrivateInstallDir, 0, scanMode | SCAN_FORWARD_LOCKED);&lt;/p&gt;&lt;p&gt;安装应用的过程&lt;br /&gt;1.scanDirLI(File dir, int flags, int scanMode) 遍历安装指定目录下的文件&lt;/p&gt;&lt;p&gt;2.scanPackageLI(File scanFile,&lt;br /&gt;&amp;nbsp; File destCodeFile, File destResourceFile, int parseFlags,&lt;br /&gt;&amp;nbsp; int scanMode) 安装package文件&lt;/p&gt;&lt;p&gt;3.scanPackageLI(&lt;br /&gt;&amp;nbsp; File scanFile, File destCodeFile, File destResourceFile,&lt;br /&gt;&amp;nbsp; PackageParser.Package pkg, int parseFlags, int scanMode)&lt;br /&gt;通过解析安装包parsePackage获取到安装包的信息结构&amp;nbsp;&lt;/p&gt;&lt;p&gt;4.mInstaller.install(pkgName, pkg.applicationInfo.uid,&lt;br /&gt;&amp;nbsp; pkg.applicationInfo.uid); 实现文件复制的安装过程&lt;br /&gt;（源文件路径：frameworks/base/cmds/installd/installd.install）&lt;br /&gt;&amp;nbsp;&lt;br /&gt;二、从market上下载应用：&lt;br /&gt;Google Market应用需要使用gmail账户登录才可以使用，选择某一应用后，开始下载安装包，此过程中，在手机的信号区有进度条提示，下载完成后，会自动调用Packagemanager的接口安装，调用接口如下：&lt;br /&gt;public void installPackage(final Uri packageURI, final IPackageInstallObserver observer, final int flags)&lt;br /&gt;final Uri packageURI：文件下载完成后保存的路径&lt;br /&gt;final IPackageInstallObserver observer：处理返回的安装结果&lt;br /&gt;final int flags：安装的参数，从market上下载的应用，安装参数为-r (replace)&lt;br /&gt;installPackage接口函数的安装过程：&lt;br /&gt;1.public void installPackage(&lt;br /&gt;&amp;nbsp; final Uri packageURI, final IPackageInstallObserver observer, final int flags,&lt;br /&gt;&amp;nbsp; final String installerPackageName)&lt;br /&gt;final String installerPackageName:安装完成后此名称保存在settings里，一般为null,不是关键参数&lt;br /&gt;2.File tmpPackageFile = copyTempInstallFile(packageURI, res);&lt;br /&gt;把apk文件复制到临时目录下的临时文件&lt;br /&gt;3.private void installPackageLI(Uri pPackageURI,&lt;br /&gt;&amp;nbsp; int pFlags, boolean newInstall, String installerPackageName,&lt;br /&gt;&amp;nbsp; File tmpPackageFile, PackageInstalledInfo res)&lt;br /&gt;解析临时文件，获取应用包名pkgName = PackageParser.parsePackageName(&lt;br /&gt;&amp;nbsp; tmpPackageFile.getAbsolutePath(), 0);&lt;br /&gt;4.判断如果带有参数INSTALL_REPLACE_EXISTING，则调用replacePackageLI(pkgName,&lt;br /&gt;&amp;nbsp; tmpPackageFile,&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; destFilePath, destPackageFile, destResourceFile,&lt;br /&gt;&amp;nbsp; pkg, forwardLocked, newInstall, installerPackageName,&lt;br /&gt;&amp;nbsp; res)&lt;br /&gt;5.如果没有，则调用installNewPackageLI(pkgName,&lt;br /&gt;&amp;nbsp; tmpPackageFile,&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; destFilePath, destPackageFile, destResourceFile,&lt;br /&gt;&amp;nbsp; pkg, forwardLocked, newInstall, installerPackageName,&lt;br /&gt;&amp;nbsp; res);&lt;br /&gt;6.private PackageParser.Package scanPackageLI(&lt;br /&gt;&amp;nbsp; File scanFile, File destCodeFile, File destResourceFile,&lt;br /&gt;&amp;nbsp; PackageParser.Package pkg, int parseFlags, int scanMode)&lt;br /&gt;scanPackageLI以后的流程，与开机时的应用安装流程相同。&lt;br /&gt;三、从ADB工具安装&lt;br /&gt;Android Debug Bridge (adb) 是SDK自带的管理设备的工具，通过ADB命令行的方式也可以为手机或模拟器安装应用，其入口函数源文件为pm.java&amp;nbsp;&amp;nbsp;&lt;br /&gt;(源文件路径：android/frameworks/base/cmds/pm/src/com/android/commands/pm/pm.java)&lt;br /&gt;ADB命令行的形式为adb install &amp;lt;path_to_apk&amp;gt; ,还可以带安装参数如："-l" "-r" "-i" "-t"&lt;br /&gt;函数runInstall()中判断参数&lt;br /&gt;"-l"――INSTALL_FORWARD_LOCK&lt;br /&gt;&amp;nbsp;"-r"&amp;mdash;&amp;mdash; INSTALL_REPLACE_EXISTING&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;"-i" &amp;mdash;&amp;mdash;installerPackageName&lt;br /&gt;"-t"&amp;mdash;&amp;mdash;INSTALL_ALLOW_TEST&lt;br /&gt;我们常用的参数为-r，表示覆盖安装手机上已安装的同名应用。从market上下载的应用，也是直接传入这个参数安装的。&lt;br /&gt;runInstall与market调用同样的接口完成应用安装。&lt;br /&gt;public void installPackage(android.net.Uri packageURI, android.content.pm.IPackageInstallObserver observer, int flags, java.lang.String installerPackageName)&lt;br /&gt;四、第三方应用安装――通过SD卡里的APK文件安装&lt;br /&gt;把APK安装包保存在SD卡中，从手机里访问SD卡中的APK安装包，点击就可以启动安装界面，系统应用Packageinstaller.apk处理这种方式下的安装及卸载界面流程，如下图：&lt;br /&gt;&amp;nbsp;&lt;br /&gt;PackageInstallerActivity负责解析包，判断是否是可用的Apk文件&lt;br /&gt;创建临时安装文件/data/data/com.android.packageinstaller/files/ApiDemos.apk&lt;br /&gt;并启动安装确认界面startInstallConfirm，列出解析得到的该应用基本信息。如果手机上已安装有同名应用，则需要用户确认是否要替换安装。&lt;br /&gt;确认安装后，启动InstallAppProgress，调用安装接口完成安装。&lt;br /&gt;pm.installPackage(mPackageURI, observer, installFlags);&lt;br /&gt;其它：&lt;br /&gt;1. PackageManagerService.java的内部类AppDirObserver实现了监听app目录的功能：当把某个APK拖到app目录下时，可以直接调用scanPackageLI完成安装。&lt;br /&gt;2.手机数据区目录&amp;ldquo;data/system/packages.xml&amp;rdquo;文件中，包含了手机上所有已安装应用的基本信息，如安装路径，申请的permission等信息。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;------------------------------------------------------华丽的分割线---------------------------------------------------------------&lt;/p&gt;&lt;p&gt;PackageManagerService注记&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;PackageManagerService的方法大致可以分成这样几类,&lt;br /&gt;1)从apk, xml中载入pacakge信息, 存储到内部成员变量中, 用于后面的查找. 关键的方法是scanPackageLI().&lt;br /&gt;2)各种查询操作, 包括query Intent操作.&amp;nbsp;&amp;nbsp;&lt;br /&gt;3)install package和delete package的操作. 关键的方法是installPackageLI().&lt;br /&gt;4)其它操作, 包括permission, signature, freeStorage等等.&lt;br /&gt;&lt;br /&gt;首先看看PacakgeManagerService用到的几个重要的支撑类, 然后罗列几个PackageManagerService的几个关键内部数据成员变量. 最后注记几个关键流程.&lt;br /&gt;&lt;br /&gt;PackageManagerService用到了几个重要的支撑类:&lt;br /&gt;&lt;br /&gt;PackageParser, 这个类主要用于解析apk, 分析其AndroidManifest.xml得到package的各种信息. 前已有注记文章,此不赘述. 特别的PackageParser.Package这个类用于容纳解析出的信息.&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;PackageManagerService.Settings, 用于容纳当前有效的package信息, 它是动态的. 例如, user id, shareUser, permission, signature以及origPackage(也就是mRenamedPackages)相关信息. 所谓的install package就包括从要安装的package中抽取信息更新PackageManagerService.Settings中的内容. 特别的, Settings针对shareUser和origPackage做了特别的关照. 另外, 为了加速启动速度, Settings的内容会写入到/data/system/packages.xml, packages-backup.xml, 和packages.list中, 下次启动时会直接载入.&lt;br /&gt;&lt;br /&gt;Installer, 这个类协助安装过程, 更多的是将针对文件/路径的操作放到了c/cpp实现. 真正的工作是是由installd承担的, Installer只是通过named socket "installd"连接installd, 使用简单的cmd-respond协议指挥installd完成工作. 在其'install'命令中可以看到, 其实只是创建了/data/data/&amp;lt;pkgName&amp;gt;目录而已.&lt;br /&gt;&lt;br /&gt;PackageManagerService中的几个关键成员变量:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// (pkgName =&amp;gt; Package), package is the one installed.&lt;br /&gt;&lt;br /&gt;final HashMap&amp;lt;String, PackageParser.Package&amp;gt; mPackages =&lt;br /&gt;&lt;br /&gt;&amp;nbsp; new HashMap&amp;lt;String, PackageParser.Package&amp;gt;();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// current package settings info, such as userid, origPackage&lt;br /&gt;&lt;br /&gt;// , shareUser, permission, signature, etc&lt;br /&gt;&lt;br /&gt;final Settings mSettings;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// (system uid =&amp;gt; permission), permissions read from /system/etc/permissions/&amp;lt;files&amp;gt; are stored here.&lt;br /&gt;&lt;br /&gt;// especially /system/etc/permissions/platform.xml&lt;br /&gt;&lt;br /&gt;final SparseArray&amp;lt;HashSet&amp;lt;String&amp;gt;&amp;gt; mSystemPermissions =&lt;br /&gt;&lt;br /&gt;&amp;nbsp; new SparseArray&amp;lt;HashSet&amp;lt;String&amp;gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//(pkgName =&amp;gt; sharedLib), corresponding to &amp;lt;library&amp;gt; tag&lt;br /&gt;&lt;br /&gt;final HashMap&amp;lt;String, String&amp;gt; mSharedLibraries =&lt;br /&gt;&lt;br /&gt;&amp;nbsp; new HashMap&amp;lt;String, String&amp;gt;();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// All available activities, for resolving intent&lt;br /&gt;&lt;br /&gt;final ActivityIntentResolver mActivities =&lt;br /&gt;&lt;br /&gt;&amp;nbsp; new ActivityIntentResolver();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// All available receivers, for resolving intent&lt;br /&gt;&lt;br /&gt;final ActivityIntentResolver mReceivers =&lt;br /&gt;&lt;br /&gt;&amp;nbsp; new ActivityIntentResolver();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// All available services, for resolving intent&lt;br /&gt;&lt;br /&gt;final ServiceIntentResolver mServices =&lt;br /&gt;&lt;br /&gt;&amp;nbsp; new ServiceIntentResolver();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;几个关键流程,&lt;br /&gt;&lt;br /&gt;初始化过程&lt;br /&gt;--------------&lt;br /&gt;&lt;br /&gt;PackageManagerService由SystemServer在创建ActivityManagerService后调用main创建, 是单实例的.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Slog.i(TAG, "Power Manager");&lt;br /&gt;&lt;br /&gt;&amp;nbsp; power = new PowerManagerService();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; ServiceManager.addService(Context.POWER_SERVICE, power);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Slog.i(TAG, "Activity Manager");&lt;br /&gt;&lt;br /&gt;&amp;nbsp; context = ActivityManagerService.main(factoryTest);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Slog.i(TAG, "Telephony Registry");&lt;br /&gt;&lt;br /&gt;&amp;nbsp; ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; AttributeCache.init(context);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Slog.i(TAG, "Package Manager");&lt;br /&gt;&lt;br /&gt;&amp;nbsp; pm = PackageManagerService.main(context,&lt;br /&gt;&lt;br /&gt;&amp;nbsp; factoryTest != SystemServer.FACTORY_TEST_OFF);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; ActivityManagerService.setSystemProcess();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mContentResolver = context.getContentResolver();&lt;br /&gt;&lt;br /&gt;在构造函数中, PackageManagerService会做这些工作,&lt;br /&gt;&lt;br /&gt;1)启动自己的handlerThread, 生成自己的mHandler.&amp;nbsp;&amp;nbsp;&lt;br /&gt;2)从/system/etc/permissions/的所有xml文件中, 尤其是platform.xml, 读入systemPermissions. 这些是系统默认的permission配置.&lt;br /&gt;3)扫描/system/framework/, /system/app/, /data/app/, 和/data/app-private/下的apk文件, 收集package各种信息, 更新到内部成员变量中. 这些将在PackageManagerService执行各种功能时用到. 尤其是query intent.&lt;br /&gt;&lt;br /&gt;更详尽的笔记,&lt;br /&gt;PackageManagerService&lt;br /&gt;&amp;nbsp; mHandlerThread.start();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mHandler = new PackageHandler(mHandlerThread.getLooper());&lt;br /&gt;&lt;br /&gt;&amp;nbsp; readPermissions();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mRestoredSettings = mSettings.readLP();&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --/system/framework/&lt;br /&gt;&amp;nbsp; scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_NO_DEX);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --/system/app/&lt;br /&gt;&amp;nbsp; scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --Prune any system packages that no longer exist.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --clean up any incomplete package installations&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --delete tmp files&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --/data/app/&lt;br /&gt;&amp;nbsp; scanDirLI(mAppInstallDir, 0, scanMode);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --/data/app-private/&lt;br /&gt;&amp;nbsp; scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, scanMode);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mSettings.writeLP();&lt;br /&gt;&lt;br /&gt;private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanMode)&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; PackageParser pp = new PackageParser(scanPath);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; pkg = pp.parsePackage(scanFile, scanPath, mMetrics, parseFlags);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)&lt;br /&gt;&lt;br /&gt;&amp;nbsp; setApplicationInfoPaths(pkg, codePath, resPath);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE);&lt;br /&gt;&amp;nbsp; --set mAndroidApplication and mResolveActivity to'Android' package&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --Check all shared libraries and map to their actual file path.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --check pkg.usesLibraries are contained in mSharedLibraries.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --fill in pkg.usesLibraryFiles according to pkg.usesLibraries and pkg.usesOptionalLibraries&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --check pkg.reqFeatures in mAvailableFeatures&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --if not in mSettings, create one ShareUserSettings and insert into mSettings.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --Check and note if we are renaming from an original package name&lt;br /&gt;&lt;br /&gt;&amp;nbsp; pkgSetting = mSettings.getPackageLP(pkg, origPackage, realName, suid, destCodeFile, destResourceFile, pkg.applicationInfo.flags, true, false);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; verifySignaturesLP(pkgSetting, pkg);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --Verify that this new package doesn't have any content providers that conflict with existing packages.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --get data dir. if not exists, install or create the data dir. if exists but uid not correct, reinstall.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --Perform shared library installation and dex validation and optimization, if this is not a system app.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --Request the ActivityManager to kill the process(only for existing packages)&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mSettings.insertPackageSettingLP(pkgSetting, pkg); --Add the new setting to mSettings&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mPackages.put(pkg.applicationInfo.packageName, pkg);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mProvidersByComponent and mProviders according to pkg.providers&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mServices according to pkg.services&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mReceivers according to pkg.receivers&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mActivites according to pkg.activities&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mPermissionGroups according to pkg.permissionGroups&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mSettings.mPermissionTrees or mSettings.mPermissions according to pkg.permissions&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mInstrumentation according to pkg.instrumentation&lt;br /&gt;&lt;br /&gt;&amp;nbsp; --set mProtectedBroadcasts according to pkg.protectedBroadcasts&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;install package过程&lt;br /&gt;--------------&lt;br /&gt;&lt;br /&gt;install package的入口是installPackage(). install package通常是个耗时的过程, 因此会使用到android的handler机制.&lt;br /&gt;首先, 参数封装成INIT_COPY message, 发到handlerThread.&lt;br /&gt;handlerThread收到message后, 将参数排队到mPendingInstalls中. 随后,MCS_BOUND流程将会处理这个队列, 执行安装.&lt;br /&gt;MCS_BOUND的整个安装流程借助了几个InstallParams和InstallArgs完成其中的参数和安装结果的传递. 最终会调用processPendingInstall(), 进而调用到install过程的核心 installPackageLI().&lt;br /&gt;installPackageLI()的复杂性很大程度上是考虑了1)新安装还是升级情况, 2)origPackage情况&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-----------------------------------华丽的分割线--------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;PackageParser和AndroidManifest.xml注记&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;apk包中的AndroidManifest.xml文件包含了package的各种描述信息. 分析和获取这些信息的工作是由PackageParser完成的. 这里简述之. 首先我们先罗列AndroidManifest.xml文件的简要结构, 其次在大致整理PackageParser的逻辑.&lt;br /&gt;&lt;br /&gt;AndroidManifest.xml的简要结构&lt;br /&gt;====================================&lt;br /&gt;AndroidManifest.xml的内容在frameworks/base/core/res/res/values/attrs_manifest.xml中定义. 这里简要罗列, 按照层进关系, xml element用 "tagName, Name"的形式标记, 对于某些xml element的重要属性(attribute), 用"attr NAME"标记.&lt;br /&gt;&lt;br /&gt;AndridManifest.xml&lt;br /&gt;&amp;nbsp; manifest, AndroidManifest&lt;br /&gt;&amp;nbsp; attr versionCode&lt;br /&gt;&amp;nbsp; attr versionName&lt;br /&gt;&amp;nbsp; attr sharedUserId&lt;br /&gt;&amp;nbsp; attr sharedUserLabel&lt;br /&gt;&amp;nbsp; attr installLocation&lt;br /&gt;&lt;br /&gt;&amp;nbsp; permission, AndroidManifestPermission&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr permissionGroup&lt;br /&gt;&amp;nbsp; attr protectionLevel&lt;br /&gt;&lt;br /&gt;&amp;nbsp; permission-group, AndroidManifestPermissionGroup&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&lt;br /&gt;&amp;nbsp; permission-tree, AndroidManifestPermissionTree&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&lt;br /&gt;&amp;nbsp; uses-sdk, AndroidManifestUsesSdk&lt;br /&gt;&lt;br /&gt;&amp;nbsp; uses-permission, AndroidManifestUsesPermission&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&lt;br /&gt;&amp;nbsp; uses-configuration, AndroidManifestUsesConfiguration&lt;br /&gt;&amp;nbsp; attr reqTouchScreen&lt;br /&gt;&amp;nbsp; attr requKeyboardType&lt;br /&gt;&amp;nbsp; attr reqHardKeyboard&lt;br /&gt;&amp;nbsp; attr reqNavigation&lt;br /&gt;&amp;nbsp; attr reqFiveWayNav&lt;br /&gt;&lt;br /&gt;&amp;nbsp; application, AndroidManifestApplication&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr permission&lt;br /&gt;&amp;nbsp; attr process&lt;br /&gt;&amp;nbsp; attr taskAffinity&lt;br /&gt;&amp;nbsp; attr persistent&lt;br /&gt;&lt;br /&gt;&amp;nbsp; service, AndroidManifestService&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr permission&lt;br /&gt;&amp;nbsp; attr process&lt;br /&gt;&amp;nbsp; attr enabled&lt;br /&gt;&amp;nbsp; attr exported&lt;br /&gt;&lt;br /&gt;&amp;nbsp; receiver, AndroidManifestReceiver&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr permission&lt;br /&gt;&amp;nbsp; attr process&lt;br /&gt;&amp;nbsp; attr enabled&lt;br /&gt;&amp;nbsp; attr exported&lt;br /&gt;&lt;br /&gt;&amp;nbsp; provider, AndroidManifestProvider&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr process, authorities, syncable&lt;br /&gt;&amp;nbsp; attr readPermission, writePermission, grantUriPermissions&lt;br /&gt;&amp;nbsp; attr permission&lt;br /&gt;&amp;nbsp; attr mulitprocess&lt;br /&gt;&amp;nbsp; attr enabled&lt;br /&gt;&amp;nbsp; attr exported&lt;br /&gt;&amp;nbsp; grant-uri-permission, AndroidManifestGrantUriPermission&lt;br /&gt;&amp;nbsp; attr path, pathPrefix, pathPattern&lt;br /&gt;&lt;br /&gt;&amp;nbsp; path-permission, AndroidManifestPathPermission&lt;br /&gt;&amp;nbsp; attr path, pathPrefix, pathPattern&lt;br /&gt;&amp;nbsp; attr permission, readPermission, writePermission&lt;br /&gt;&lt;br /&gt;&amp;nbsp; activity, AndroidManifestActivity&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr theme, launchMode, screenOrientation&lt;br /&gt;&amp;nbsp; attr configChanges, permission, multiprocess&lt;br /&gt;&amp;nbsp; attr process, taskAffinity, allowTaskReparenting&lt;br /&gt;&amp;nbsp; attr finishOnTaskLaunch, finishOnCloseSystemDialogs&lt;br /&gt;&amp;nbsp; attr clearTaskOnLauch, noHistory&lt;br /&gt;&amp;nbsp; attr alwaysRetainTaskState, stateNotNeeded&lt;br /&gt;&amp;nbsp; attr excludeFromRecents&lt;br /&gt;&amp;nbsp; attr enabled, exported&lt;br /&gt;&amp;nbsp; attr windowSoftInputMode&lt;br /&gt;&lt;br /&gt;&amp;nbsp; activity-alias, AndroidManifestActivityAlias&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr targetActivity&lt;br /&gt;&amp;nbsp; attr permission&lt;br /&gt;&amp;nbsp; attr enabled, exported&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; uses-library, AndroidManifestUsesLibrary&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&amp;nbsp; attr required&lt;br /&gt;&lt;br /&gt;&amp;nbsp; instrumentation, AnroidManifestInstrumentation&lt;br /&gt;&amp;nbsp; attr name, label, icon&lt;br /&gt;&amp;nbsp; attr targetPackage, handleProfiling&lt;br /&gt;&amp;nbsp; attr functionalTest&lt;br /&gt;&lt;br /&gt;&amp;nbsp; uses-feature, AndroidManifestUsesFeature&lt;br /&gt;&amp;nbsp; attr glEsVersion&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&amp;nbsp; attr required&lt;br /&gt;&lt;br /&gt;&amp;nbsp; supports-screens, AndroidManifestSupportsScreens&lt;br /&gt;&amp;nbsp; attr smallScreens, normalScreens, largeScreens&lt;br /&gt;&amp;nbsp; attr resizeable, anyDensity&lt;br /&gt;&lt;br /&gt;&amp;nbsp; protected-broadcast, AndroidManifestProtectedBroadcast&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; adopt-permissions, AndroidManifestOriginalPackage&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&lt;br /&gt;还有几个特别的xml element, 可以有多个parent element.&lt;br /&gt;&amp;nbsp; application&lt;br /&gt;&amp;nbsp; activity, receiver, provider, service&lt;br /&gt;&amp;nbsp; permission, permissionGroup&lt;br /&gt;&amp;nbsp; instrumentation&lt;br /&gt;&amp;nbsp; meta-data, AndroidManifestMetaData&lt;br /&gt;&amp;nbsp; attr name, value, resource&lt;br /&gt;&lt;br /&gt;&amp;nbsp; activity, receiver, service&lt;br /&gt;&amp;nbsp; intent-filter, AndroidManifestIntentFilter&lt;br /&gt;&amp;nbsp; attr label, icon, priority&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; action, AndroidManifestAction&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&lt;br /&gt;&amp;nbsp; data, AndroidManifestData&lt;br /&gt;&amp;nbsp; attr mimeType, scheme, host&lt;br /&gt;&amp;nbsp; attr port, path, pathPrefix&lt;br /&gt;&amp;nbsp; attr pathPattern&lt;br /&gt;&lt;br /&gt;&amp;nbsp; category, AndroidManifestCategory&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&lt;br /&gt;&amp;nbsp; intent, Intent&lt;br /&gt;&amp;nbsp; attr action, data, mimeType&lt;br /&gt;&amp;nbsp; attr targetPackage, targetClass&lt;br /&gt;&lt;br /&gt;&amp;nbsp; category, IntentCategory&lt;br /&gt;&amp;nbsp; attr name&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp; extra, Extra&lt;br /&gt;&amp;nbsp; attr name, value&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PackageParser的逻辑&lt;br /&gt;====================================&lt;br /&gt;PackageParser的parsePackage()方法会读取apk包中的AndroidManifest.xml文件, 调用各子par***XX()方法, 解析出包信息. 同时, PackageParser定义了一些class, 容纳这些解析得到的信息. 下面是对应的关系.&lt;br /&gt;&lt;br /&gt;class xml elements&lt;br /&gt;------------- --------------------------------------&lt;br /&gt;Package package&lt;br /&gt;Permission permission, permission-tree&lt;br /&gt;PermissionGroup permission-group&lt;br /&gt;Activity activity, activity-alias, receiver&lt;br /&gt;Service service&lt;br /&gt;Provider provider&lt;br /&gt;Instrumentation instrumentation&lt;br /&gt;ActivityIntentInfo intent-filter @ activity or receiver&lt;br /&gt;ServiceIntentInfo intent-filter @ service&lt;br /&gt;&lt;br /&gt;PacakgeParser的结果主要被PackageManagerService使用.&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2506635.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/05/17/2506635.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2012/05/10/2494811.html</id><title type="text">标记化结构初始化语法(C语言)</title><summary type="text">以前在看Linux代码时，就对它的结构体初始化写法感到奇怪，所有的初始化代码都写清了变量名，并且变量名前面还有一个诡异的点。最近学习Linux设备驱动，又遇到了，就查了一下，发现自己的知识果然纰漏不少，此种初始化写法并不是什么特殊的代码风格，而是所谓的C语言标记化结构初始化语法（designated initializer），而且还是一个ISO标准。[cpp]view plaincopy#include&lt;stdio.h&gt;#include&lt;stdlib.h&gt;structoperators{void(*read1)(char*);void(*read2)(char*);vo</summary><published>2012-05-10T10:21:00Z</published><updated>2012-05-10T10:21:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/05/10/2494811.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/05/10/2494811.html"/><content type="html">&lt;p&gt;&amp;nbsp; 以前在看Linux代码时，就对它的结构体初始化写法感到奇怪，所有的初始化代码都写清了变量名，并且变量名前面还有一个诡异的点。最近学习Linux设备驱动，又遇到了，就查了一下，发现自己的知识果然纰漏不少，此种初始化写法并不是什么特殊的代码风格，而是所谓的C语言标记化结构初始化语法（designated initializer），而且还是一个ISO标准。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="dp-highlighter bg_cpp"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;strong&gt;[cpp]&lt;/strong&gt;&amp;nbsp;&lt;a class="ViewSource" title="view plain" href="http://blog.csdn.net/chen_chun_guang/article/details/6199932"&gt;view plain&lt;/a&gt;&lt;a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/chen_chun_guang/article/details/6199932"&gt;copy&lt;/a&gt;&lt;div&gt;&lt;object id="ZeroClipboardMovie_1" width="18" height="18" align="middle" bgcolor="#ffffff" data="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash"&gt;&lt;param name="src" value="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" /&gt;&lt;param name="loop" value="loop" /&gt;&lt;param name="menu" value="false" /&gt;&lt;param name="quality" value="best" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="false" /&gt;&lt;param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;param name="flashvars" value="id=1&amp;amp;width=18&amp;amp;height=18" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-cpp" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="preprocessor"&gt;#include&amp;nbsp;&amp;lt;stdio.h&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="preprocessor"&gt;#include&amp;nbsp;&amp;lt;stdlib.h&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;struct&lt;/span&gt;&lt;span&gt;&amp;nbsp;operators&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;(*read1)(&lt;/span&gt;&lt;span class="datatypes"&gt;char&lt;/span&gt;&lt;span&gt;&amp;nbsp;*);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;(*read2)(&lt;/span&gt;&lt;span class="datatypes"&gt;char&lt;/span&gt;&lt;span&gt;&amp;nbsp;*);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;(*read3)(&lt;/span&gt;&lt;span class="datatypes"&gt;char&lt;/span&gt;&lt;span&gt;&amp;nbsp;*);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="datatypes"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;n;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;};&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;read1(&lt;/span&gt;&lt;span class="datatypes"&gt;char&lt;/span&gt;&lt;span&gt;&amp;nbsp;*data)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;span class="string"&gt;"read1:&amp;nbsp;%s/n"&lt;/span&gt;&lt;span&gt;,data);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;read2(&lt;/span&gt;&lt;span class="datatypes"&gt;char&lt;/span&gt;&lt;span&gt;&amp;nbsp;*data)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;span class="string"&gt;"read2:&amp;nbsp;%s/n"&lt;/span&gt;&lt;span&gt;,data);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;read3(&lt;/span&gt;&lt;span class="datatypes"&gt;char&lt;/span&gt;&lt;span&gt;&amp;nbsp;*data)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&lt;span class="string"&gt;"read3:&amp;nbsp;%s/n"&lt;/span&gt;&lt;span&gt;,data);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span class="datatypes"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;main()&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//传统的初始化方法&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//struct&amp;nbsp;operators&amp;nbsp;my_op&amp;nbsp;=&amp;nbsp;{read1,&amp;nbsp;read2,&amp;nbsp;read3,&amp;nbsp;100};&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//所谓的标记化结构初始化语法&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;struct&lt;/span&gt;&lt;span&gt;&amp;nbsp;operators&amp;nbsp;my_op&amp;nbsp;=&amp;nbsp;{.read2&amp;nbsp;=&amp;nbsp;read2,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.read1&amp;nbsp;=&amp;nbsp;read1,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.read3&amp;nbsp;=&amp;nbsp;read3,&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.n&amp;nbsp;=&amp;nbsp;100};&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;my_op.read1(&lt;span class="string"&gt;"wangyang"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;my_op.read2(&lt;span class="string"&gt;"wangyang"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;my_op.read3(&lt;span class="string"&gt;"wangyang"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;0;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;重点就在于main()函数中对my_op结构体的初始化语句，使用点加变量名进行初始化。用过python的人会马上感觉到这与关键字传参是多么的相似。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;那它的好处在哪里呢？我想好处有三:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;strong&gt;首先，标记传参不用理会参数传递的顺序，正如我上面的例子表示的那样，我是先初始化了read2，然后再初始化了read1，程序员不用记忆参数的顺序；&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 其次，我们可以选择性传参，在传统C语言顺序传参中，如果你只想对第三个变量进行初始化，那么你不得不给第一个, 第二个参数进行初始化，而有时候一个变量并没有很合适的默认值，而使用标记初始化法，你可以相当自由地对你有把握的参数进行初始化；&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 第三，扩展性更好，如果你要在该结构体中增加一个字段，传统方式下，为了考虑代码修改量，你最好将新添加的字段放在这个结构体的最后面，否则你将要面对大量且无趣的修改，你可能觉得放在哪里没什么关系，但是我们都习惯了，姓名下面是性别，性别下面是年龄，接着是兴趣爱好，最后是事迹描述，如果年龄放在了最后面，难道不别扭么？！&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;有人提到，该种语法还有利于提高性能，木有感觉出来，我在这里就不谈这点了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;其实，该种初始化语法并不是什么新技术，新定义，它就是ISO C99的一个标准用法，也就是说99年就有了，再说Linus也不会去赶什么时髦的，据说C Primer Plus第五版中提到了这点，不过，我没有看过该书，遗憾，我是直接投入了面向对象的怀抱。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;GCC有扩展标记化结构初始化语法，写法是下面这样的：&lt;/p&gt;&lt;p&gt;struct operators my_op = {read2 : read2, read1 : read1, read3 : read3,};&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;转自:&amp;nbsp;&lt;a href="http://www.hustyx.com/cplusplus/agtodXN0eWl4aWFuZ3IPCxIHQXJjaGl2ZRihigcM"&gt;http://www.hustyx.com/cplusplus/agtodXN0eWl4aWFuZ3IPCxIHQXJjaGl2ZRihigcM&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2494811.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/05/10/2494811.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2012/02/07/2341441.html</id><title type="text">Android adb root权限</title><summary type="text">方法：修改./default.prop把ro.secure设为0，persist.service.adb.enable设为1，adbd进程就会以root用户的身份启动。原理：可以看一下Android系统根目录下的/init.rc的片段：... ...# adbd is controlled by the persist.service.adb.enable system propertyservice adbd /sbin/adbd disabled# adbd on at boot in emulatoron property:ro.kernel.qemu=1 start adbdon pr</summary><published>2012-02-07T06:18:00Z</published><updated>2012-02-07T06:18:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/02/07/2341441.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/02/07/2341441.html"/><content type="html">&lt;p&gt;方法：&lt;/p&gt;&lt;p&gt;修改./default.prop&lt;/p&gt;&lt;p&gt;把ro.secure设为0，persist.service.adb.enable设为1，adbd进程就会以root用户的身份启动。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;原理：&lt;/p&gt;&lt;p&gt;可以看一下Android系统根目录下的/init.rc的片段：&lt;/p&gt;&lt;p&gt;... ...&lt;/p&gt;&lt;p&gt;# adbd is controlled by the persist.service.adb.enable system property&lt;/p&gt;&lt;p&gt;service adbd /sbin/adbd&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;disabled&lt;/p&gt;&lt;p&gt;# adbd on at boot in emulator&lt;/p&gt;&lt;p&gt;on property:ro.kernel.qemu=1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;start adbd&lt;/p&gt;&lt;p&gt;on property:persist.service.adb.enable=1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;start adbd&lt;/p&gt;&lt;p&gt;on property:persist.service.adb.enable=0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;stop adbd&lt;/p&gt;&lt;p&gt;... ...&lt;/p&gt;&lt;p&gt;这里定义了一个触发器，只要persist.service.adb.enable值被置为1，就会启动/sbin/adbd。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在build目录下搜索一下，发现了main.mk中有这样的代码片段&lt;/p&gt;&lt;p&gt;## user/userdebug ##&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;user_variant := $(filter userdebug user,$(TARGET_BUILD_VARIANT))&lt;/p&gt;&lt;p&gt;enable_target_debugging := true&lt;/p&gt;&lt;p&gt;ifneq (,$(user_variant))&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Target is secure in user builds.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;tags_to_install := user&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ifeq ($(user_variant),userdebug)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;# Pick up some extra useful tools&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;tags_to_install += debug&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;else&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;# Disable debugging in plain user builds.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;enable_target_debugging :=&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;endif&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# TODO: Always set WITH_DEXPREOPT (for user builds) once it works on OSX.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Also, remove the corresponding block in config/product_config.make.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;WITH_DEXPREOPT := true&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;endif&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Disallow mock locations by default for user builds&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;else # !user_variant&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Turn on checkjni for non-user builds.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ADDITIONAL_BUILD_PROPERTIES += ro.kernel.android.checkjni=1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Set device insecure for non-user builds.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Allow mock locations by default for non user builds&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=1&lt;/p&gt;&lt;p&gt;endif # !user_variant&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;ifeq (true,$(strip $(enable_target_debugging)))&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Target is more debuggable and adbd is on by default&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=1 persist.service.adb.enable=1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Include the debugging/testing OTA keys in this build.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;INCLUDE_TEST_OTA_KEYS := true&lt;/p&gt;&lt;p&gt;else # !enable_target_debugging&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;# Target is less debuggable and adbd is off by default&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=0 persist.service.adb.enable=0&lt;/p&gt;&lt;p&gt;endif # !enable_target_debugging&lt;/p&gt;&lt;p&gt;这段代码我大致解释一下：&lt;/p&gt;&lt;p&gt;主要通过判断当前的编译模式来给几个属性赋予不同的值，然后把属性存储在ADDITIONAL_DEFAULT_PROPERTIES这个变量中，这个变量在后面是要写到根目录下的/default.prop中去，在系统启动时被属性服务加载的。也就是说我们在/default.prop中看到的几个属性的值是在这里设置的。&lt;/p&gt;&lt;p&gt;只看两个属性ro.secure，persist.service.adb.enable。当前是user模式的话，编译系统会把ro.secure置为1，把persist.service.adb.enable置为0.也就是说，用user模式编译出来的系统运行在安全模式下，adbd默认关闭。即使通过设置属性的方式打开，adbd进程的用户也是shell，不具有root权限。这样，普通用户或者开发者拿到一个机器后，通过PC运行adb shell时，是以shell用户登录机器的。&lt;/p&gt;&lt;p&gt;好了，现在把ro.secure置为0，再重新编译，只要设置属性persist.service.adb.enable的值为1，adbd进程就会以root用户的身份启动。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2341441.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/02/07/2341441.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2012/01/31/2332727.html</id><title type="text">java中Thread与Runnable的区别</title><summary type="text">在java中可有两种方式实现多线程，一种是继承Thread类，一种是实现Runnable接口；Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了，但是一个类只能继承一个父类，这是此方法的局限，下面看例子：package org.thread.demo;class MyThread extends Thread{private String name;public MyThread(String name) {super();this.name = name;}public void run(){for(int i</summary><published>2012-01-31T03:14:00Z</published><updated>2012-01-31T03:14:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2012/01/31/2332727.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2012/01/31/2332727.html"/><content type="html">&lt;p&gt;&lt;span&gt;在java中可有两种方式实现多线程，一种是继承Thread类，一种是实现Runnable接口；&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的&lt;/span&gt;&lt;br /&gt;&lt;span&gt;run()方法就可以实现多线程操作了，但是一个类只能继承一个父类，这是此方法的局限，&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;下面看例子：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.thread.demo;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;class MyThread extends Thread{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;private String name;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public MyThread(String name) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;super();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;this.name = name;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public void run(){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;for(int i=0;i&amp;lt;10;i++){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;System.out.println("线程开始："+this.name+",i="+i);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.thread.demo;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public class ThreadDemo01 {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt1=new MyThread("线程a");&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt2=new MyThread("线程b");&lt;/span&gt;&lt;br /&gt;&lt;span&gt;mt1.run();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;mt2.run();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;但是，此时结果很有规律，先第一个对象执行，然后第二个对象执行，并没有相互运行。在JDK的文档中可以发现，一旦调用start()方法，则会通过JVM找到run()方法。下面启动&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;start()方法启动线程：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.thread.demo;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public class ThreadDemo01 {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt1=new MyThread("线程a");&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt2=new MyThread("线程b");&lt;/span&gt;&lt;br /&gt;&lt;span&gt;mt1.start();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;mt2.start();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;};这样程序可以正常完成交互式运行。那么为啥非要使用start();方法启动多线程呢？&lt;/span&gt;&lt;br /&gt;&lt;span&gt;在JDK的安装路径下，src.zip是全部的java源程序，通过此代码找到Thread中的start()方法的定义，可以发现此方法中使用了private native void start0();其中native关键字表示可以调用操作系统的底层函数，那么这样的技术成为JNI技术（java Native Interface）&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&amp;middot;Runnable接口&lt;/span&gt;&lt;br /&gt;&lt;span&gt;在实际开发中一个多线程的操作很少使用Thread类，而是通过Runnable接口完成。&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public interface Runnable{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public void run();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;例子：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.runnable.demo;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;class MyThread implements Runnable{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;private String name;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public MyThread(String name) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;this.name = name;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public void run(){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;for(int i=0;i&amp;lt;100;i++){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;System.out.println("线程开始："+this.name+",i="+i);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span&gt;但是在使用Runnable定义的子类中没有start()方法，只有Thread类中才有。此时观察Thread类，有一个构造方法：public Thread(Runnable targer)&lt;/span&gt;&lt;br /&gt;&lt;span&gt;此构造方法接受Runnable的子类实例，也就是说可以通过Thread类来启动Runnable实现的多&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;线程。（start()可以协调系统的资源）:&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.runnable.demo;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;import org.runnable.demo.MyThread;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public class ThreadDemo01 {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt1=new MyThread("线程a");&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt2=new MyThread("线程b");&lt;/span&gt;&lt;br /&gt;&lt;span&gt;new Thread(mt1).start();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;new Thread(mt2).start();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&amp;middot; 两种实现方式的区别和联系：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;在程序开发中只要是多线程肯定永远以实现Runnable接口为主，因为实现Runnable接口相比&lt;/span&gt;&lt;br /&gt;&lt;span&gt;继承Thread类有如下好处：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;-&amp;gt;避免点继承的局限，一个类可以继承多个接口。&lt;/span&gt;&lt;br /&gt;&lt;span&gt;-&amp;gt;适合于资源的共享&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;以卖票程序为例，通过Thread类完成：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.demo.dff;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;class MyThread extends Thread{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;private int ticket=10;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public void run(){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;for(int i=0;i&amp;lt;20;i++){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;if(this.ticket&amp;gt;0){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;System.out.println("賣票：ticket"+this.ticket--);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span&gt;下面通过三个线程对象，同时卖票：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.demo.dff;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public class ThreadTicket {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt1=new MyThread();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt2=new MyThread();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt3=new MyThread();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;mt1.start();//每个线程都各卖了10张，共卖了30张票&lt;/span&gt;&lt;br /&gt;&lt;span&gt;mt2.start();//但实际只有10张票，每个线程都卖自己的票&lt;/span&gt;&lt;br /&gt;&lt;span&gt;mt3.start();//没有达到资源共享&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;如果用Runnable就可以实现资源共享，下面看例子：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.demo.runnable;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;class MyThread implements Runnable{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;private int ticket=10;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public void run(){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;for(int i=0;i&amp;lt;20;i++){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;if(this.ticket&amp;gt;0){&lt;/span&gt;&lt;br /&gt;&lt;span&gt;System.out.println("賣票：ticket"+this.ticket--);&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;package org.demo.runnable;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public class RunnableTicket {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span&gt;MyThread mt=new MyThread();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;new Thread(mt).start();//同一个mt，但是在Thread中就不可以，如果用同一&lt;/span&gt;&lt;br /&gt;&lt;span&gt;new Thread(mt).start();//个实例化对象mt，就会出现异常&lt;/span&gt;&lt;br /&gt;&lt;span&gt;new Thread(mt).start();&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span&gt;虽然现在程序中有三个线程，但是一共卖了10张票，也就是说使用Runnable实现多线程可以达到资源共享目的。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Runnable接口和Thread之间的联系：&lt;/span&gt;&lt;br /&gt;&lt;span&gt;public class Thread extends Object implements Runnable&lt;/span&gt;&lt;br /&gt;&lt;span&gt;发现Thread类也是Runnable接口的子类。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2332727.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2012/01/31/2332727.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2011/12/14/2287187.html</id><title type="text">linux主设备号和次设备号</title><summary type="text">Linux的设备管理是和文件系统紧密结合的，各种设备都以文件的形式存放在/dev目录下，称为设备文件。应用程序可以打开、关闭和读写这些设备文件， 完成对设备的操作，就像操作普通的数据文件一样。为了管理这些设备，系统为设备编了号，每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备，而次设备号用来区分同一类型的多个设备。对于常用设备，Linux有约定俗成的编号，如硬盘的主设备号是3。 Linux为所有的设备文件都提供了统一的操作函数接口，方法是使用数据结构struct file_operations。这个数据结构中包括许多操作函数的指针，如open()、close()、read()</summary><published>2011-12-14T02:10:00Z</published><updated>2011-12-14T02:10:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2011/12/14/2287187.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2011/12/14/2287187.html"/><content type="html">&lt;div id="app-share-content"&gt;&lt;span style="font-size: medium;"&gt;Linux的设备管理是和文件系统紧密结合的，各种设备都以文件的形式存放在/dev目录下，称为设备文件。应用程序可以打开、关闭和读写这些设备文件， 完成对设备的操作，就像操作普通的数据文件一样。为了管理这些设备，系统为设备编了号，每个设备号又分为主设备号和次设备号。&lt;span style="color: #00ff00;"&gt;主设备号用来区分不同种类的设备，而次设备号用来区分同一类型的多个设备。&lt;/span&gt;对于常用设备，Linux有约定俗成的编号，如硬盘的主设备号是3。&lt;/span&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;span style="font-size: medium;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Linux为所有的设备文件都提供了统一的操作函数接口，方法是使用数据结构struct file_operations。这个数据结构中包括许多操作函数的指针，如open()、close()、read()和write()等，但由于外设 的种类较多，操作方式各不相同。Struct file_operations结构体中的成员为一系列的接口函数，如用于读/写的read/write函数和用于控制的ioctl等。打开一个文件就是 调用这个文件file_operations中的open操作。不同类型的文l件有不同的file_operations成员函数，如普通的磁盘数据文件， 接口函数完成磁盘数据块读写操作；而对于各种设备文件，则最终调用各自驱动程序中的I/O函数进行具体设备的操作。这样，应用程序根本不必考虑操作的是设 备还是普通文件，可一律当作文件处理，具有非常清晰统一的I/O接口。所以file_operations是文件层次的I/O接口。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: xx-small;"&gt;转自：&lt;/span&gt;&lt;a href="http://hi.baidu.com/wudaovip/blog/item/479b451e95c475f81ad57621.html"&gt;&lt;span style="font-size: xx-small;"&gt;http://hi.baidu.com/wudaovip/blog/item/479b451e95c475f81ad57621.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff9900; font-size: medium;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #00ff00;"&gt;设备号是在驱动module中分配并注册的，也就是说，驱动module拥有这个设备号&lt;/span&gt;(我的理解)，而/dev目录下的设备文件是根据这个设备号创建的，因此，&lt;span style="color: #00ff00;"&gt;当访问/dev目录下的设备文件时，驱动module就知道，自己该出场服务了(当然是由内核通知)。&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #00ff00;"&gt;在Linux内核看来，主设备号标识设备对应的驱动程序，告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务；而次设备号则用来标识具体且唯一的某个设备。&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在内核中，用dev_t类型(其实就是一个32位的无符号整数)的变量来保存设备的主次设备号，其中高12位表示主设备号，低20位表示次设备号。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 设备获得主次设备号有两种方式：一种是手动给定一个32位数，并将它与设备联系起来(即用某个函数注册)；另一种是调用系统函数给设备动态分配一个主次设备号。&lt;br /&gt;&lt;br /&gt;对于手动给定一个主次设备号，使用以下函数：&lt;br /&gt;int&amp;nbsp;&lt;strong&gt;register_chrdev_region&lt;/strong&gt;(dev_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; first,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned int -count,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *name)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 其中first是我们手动给定的设备号，count是所请求的连续设备号的个数，而name是和该设备号范围关联的设备名称，它将出现在/proc/devices和sysfs中。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 比如，若first为0x3FFFF0，count为0x5，那么该函数就会为5个设备注册设备号，分别是0x3FFFF0、 0x3FFFF1、 0x3FFFF2、 0x3FFFF3、 0x3FFFF4，其中0x3(高12位)为这5个设备所共有的主设备号(也就是说这5个设备都使用同一个驱动程序)。而0xFFFF0、 0xFFFF1、 0xFFFF2、 0xFFFF3、 0xFFFF4就分别是这5个设备的次设备号了。需要注意的是，若count的值太大了，那么所请求的设备号范围可能会和下一个主设备号重叠。比如若 first还是为0x3FFFF0，而count为0x11，那么first+count=0x400001，也就是说为最后两个设备分配的主设备号已经不是0x3，而是0x4了！用这种方法注册设备号有一个缺点，那就是若该驱动module被其他人广泛使用，那么无法保证注册的设备号是其他人的 Linux系统中未分配使用的设备号。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;对于动态分配设备号，使用以下函数：&lt;br /&gt;int&amp;nbsp;&lt;strong&gt;alloc_chrdev_region&lt;/strong&gt;(dev_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *dev,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned int -&lt;/span&gt;&lt;span style="color: #ff9900; font-size: medium;"&gt;firstminor,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned int -&lt;/span&gt;&lt;span style="color: #ff9900; font-size: medium;"&gt;count,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *name)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 该函数需要传递给它指定的第一个次设备号firstminor(一般为0)和要分配的设备数count，以及设备名，调用该函数后自动分配得到的设备号保存在dev中。&lt;span style="color: #00ff00;"&gt;动态分配设备号可以避免手动指定设备号时带来的缺点，但是它却也有自己的缺点，那就是无法预先在/dev下创建设备节点，&lt;/span&gt;因为动态分配设备号不能保证在每次加载驱动module时始终一致(其实若在两次加载同一个驱动module之间并没有加载其他的module，那么自动分配的设备号还是一致的，因为内核分配设备号并不是随机的，但是书上说某些内核开发人员预示不久的将来会用随机方式进行处理)，不过，这个缺点可以避免，因为在加载驱动module后，我们可以读取/proc/devices文件以获得Linux内核分配给该设备的主设备号。&lt;br /&gt;&lt;br /&gt;与主次设备号相关的3个宏：&lt;br /&gt;MAJOR(dev_t dev)：根据设备号dev获得主设备号；&lt;br /&gt;MINOR(dev_t dev)：根据设备号dev获得次设备号；&lt;br /&gt;MKDEV(int major, int minor)：根据主设备号major和次设备号minor构建设备号。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff9900; font-size: medium;"&gt;另解:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff9900; font-size: medium;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Linux的设备管理是和文件系统紧密结合的，把设备和文件关联起来，这样系统调用可以直接用操作文件一样的方法来操作设备。各种设备都以文件的形式存放在/dev目录下，称为设备文件。应用程序可以打开、关闭和读写这些设备文件，完成对设备的操作，就像操作普通的数据文件一样。为了管理这些设备，系统为设备编了号，每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备，而次设备号用来区分同一类型的多个设备。对于常用设备，Linux有约定俗成的编号，如硬盘的主设备号是3。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: xx-small;"&gt;转自：&lt;/span&gt;&lt;a href="http://fanyihui1986.blog.163.com/blog/static/784485920091132043905/"&gt;&lt;span style="font-size: xx-small;"&gt;http://fanyihui1986.blog.163.com/blog/static/784485920091132043905/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="appShareUrl"&gt;来自:&amp;nbsp;&lt;a href="http://hi.baidu.com/vv1133/blog/item/08d271941e1f3213d31b70bd.html" target="_blank"&gt;http://hi.baidu.com/vv1133/blog/item/08d271941e1f3213d31b70bd.html&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2287187.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2011/12/14/2287187.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/myitm/archive/2011/12/05/2276977.html</id><title type="text">android下m、mm、mmm编译命令的使用</title><summary type="text">通过查看android源码目录下的build/envsetup.sh文件，可知：- m: Makes from the top of the tree.- mm: Builds all of the modules in the current directory.- mmm: Builds all of the modules in the supplied directories.要想使用这些命令，首先需要在android源码根目录执行. build/envsetup.shm：编译所有的模块mm：编译当前目录下的模块，当前目录下要有Android.mk文件mmm：编译指定路径下的模块，指定</summary><published>2011-12-05T08:28:00Z</published><updated>2011-12-05T08:28:00Z</updated><author><name>心随灵动</name><uri>http://www.cnblogs.com/myitm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/myitm/archive/2011/12/05/2276977.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/myitm/archive/2011/12/05/2276977.html"/><content type="html">&lt;p&gt;通过查看android源码目录下的build/envsetup.sh文件，可知：&amp;nbsp;&lt;br /&gt;- m:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Makes from the top of the tree.&amp;nbsp;&lt;br /&gt;- mm:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Builds all of the modules in the current directory.&amp;nbsp;&lt;br /&gt;- mmm:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Builds all of the modules in the supplied directories.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;要想使用这些命令，首先需要在android源码根目录执行. build/envsetup.sh&amp;nbsp;&lt;br /&gt;&lt;br /&gt;m：编译所有的模块&amp;nbsp;&lt;br /&gt;mm：编译当前目录下的模块，当前目录下要有Android.mk文件&amp;nbsp;&lt;br /&gt;mmm：编译指定路径下的模块，指定路径下要有Android.mk文件&amp;nbsp;&lt;br /&gt;&lt;br /&gt;下面举个例子说明，假设我要编译android下的libjpeg模块，当前目录为源码根目录，方法如下：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;1、. build/envsetup.sh&amp;nbsp;&lt;br /&gt;2、mmm external/jpeg/&amp;nbsp;&lt;br /&gt;&lt;br /&gt;或者 ：&amp;nbsp;&lt;br /&gt;&lt;br /&gt;1、. build/envsetup.sh&amp;nbsp;&lt;br /&gt;2、cd external/jpeg&amp;nbsp;&lt;br /&gt;3、mm&amp;nbsp;&lt;br /&gt;&lt;br /&gt;最后说明一下，envsetup.sh只要source一次就够了，source之后还可以用croot命令返回到源码根目录，很好用。&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/myitm/aggbug/2276977.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/myitm/archive/2011/12/05/2276977.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
