1. Android
谷歌、基于Linux、开源手机平台、使用Java语言,(由Linux操作系统、中间件和应用软件组成)
2. iOS
多点触摸操作是iOS的用户界面基础,(核心操作系统层、核心服务层、媒体层和可轻触层),操作系统Darwin为基础
3. 黑莓
加拿大RIM公司、针对商务应用、支持电子邮件推送功能,具有很高的安全性和可靠性
4. Windows Phone 8
2012.6发布,第一个支持双核CPU的WP版本
5. Linux
由计算机Linux操作系统演变而来,开放源代码,降低手机的软件成本
1. 在内存和进程管理方面,Android具有自己的运行时和虚拟机
2. 在界面设计上,提供了丰富的界面控件
3. Android提供轻量级的进程间通讯机制Intent,使用跨进程组件和发送系统级广播成为可能
4. Android提供了Service作为无用户界面、长时间后台运行的组件
5. Android支持高效、快速的数据存储方式
6. 为了便于跨进程共享数据,Android提供了通用的共享数据接口ContentProvider
7. Android支持Widget插件
8. Android NDK支持使用本地代码(C或C++)开发应用程序的部分核心模块
Android是基于Linux内核的软件平台和操作系统,采用了软件堆层(Software Stack),共分为4层
1. Linux内核
提供由操作系统内核管理的底层基础功能
2. 中间件层
由 函数库 和 Android运行时(核心库、ART虚拟机) 构成
函数库(Surface Manager以及所有其他英文…)
3. 应用程序框架层
提供了Android平台基本的管理功能和组件重用机制
(xxx Manager、Content Providers、View System)
4. 应用程序层
提供了一系列核心应用程序
(题:通讯录属于哪一层?应用程序层)
1. Android模拟器
Android模拟器主要用来调试Android应用程序,模拟器可以仿真手机的绝大部分硬件和软件功能,支持加载SD卡映像文件,更改模拟网络状态、延迟和速度,模拟电话呼叫和接收短信等。
不支持:接听真实电话、USB连接、摄像头捕获、连接状态、电池电量等
2. Android调试桥
(ADB,Android Debug Bridge)用于连接Android设备或模拟器的工具,负责将应用程序安装到模拟器和设备中,或从模拟器或设备中传输文件。
3. DDMS
(Dalvik Debug Monitor Service),Android系统中内置的调试工具,监视Android系统中进程、堆栈信息,查看logcat日志,实现端口转发服务和屏幕截图功能,模拟器电话呼叫和SMS短信,以及浏览Android模拟器文件系统等
记java、xml的位置以及AndroidManifest.xml(注册)
1. bin目录保存了编译过程中产生的文件,以及最终产生的apk文件
2. layout目录用来保存与用户界面相关的布局文件,产生了mail.xml
3. values目录生成了strings.xml,将应用程序名称“HelloAndroid”和界面显示的“Hello world,HelloAndroidActivity!”保存在这个文件中
1. R.java文件是ADT自动生成的文件,包含对drawable、layout和values目录内的资源引用指针,Android程序能够直接通过R类引用目录中的资源。
R.java不能手动修改,所有代码必须由ADT自动生成。如果向资源目录中增加或删除了资源文件,则需要在工程名称上右击,选择Refresh来更新R.java文件中的代码
2. AndroidManifest.xml是XML格式的Android程序声明文件,包含了Android系统运行Android程序前所必须掌握的重要信息,这些信息包括应用程序名称、图表、包名称、模块组成、授权和SDK最低版本等,而且每个Android程序必须在根目录下包含一个AndroidManifest.xml文件。
manifest元素仅能包含一个application元素,application元素中能够声明Android程序中最重要的四个组成部分(包括:Activity、Service、BroadcastReceiver和ContentProvider),所定义的属性将影响所有组成部分。
程序生命周期(图:记优先级)
前台进程是Android系统中最重要的进程,是与用户正在交互的进程,所以被排放在首位;可见进程和服务进程都是包含服务的进程,不在前台与用户交互,不响应界面时间的进程,而是在后台长期运行,所以,他们被排放在前台进程之后;而后台进程和空进程是不包含任何已经启动服务的进程,在系统资源比较紧张的时候,会首先被清除,所以他们被排放在最后。
题:根据条件判断进程类型?
1. 前台进程
前台进程是Android系统中最重要的进程
❑ 进程中的Activity正在与用户进行交互
❑ Service被Activity调用,而且这个Activity正在与用户进行交互
❑ Service正在执行生命周期中的回调函数,如onCreate()、onStart()或onDestroy()
❑ 进程的Broadcase Receiver正在执行onReceive()函数
2. 可见进程
❑ 可见进程指部分程序界面能够被用户看见,却不在前台与用户交互,不响应界面事件的进程
❑ 如果一个进程包含Service,且这个Service正在被用户可见的Activity调用,此进程同样被视为可见进程
3. 服务进程
❑ 包含已启动服务的进程
❑ Android系统除非不能保证前台进程或可视进程所必要的资源,否则不强行清除服务进程
4. 后台进程
❑ 指不包含任何已经启动的服务,而且没有任何用户可见的Activity的进程
❑ Android系统中一般存在数量较多的后台进程
5. 空进程
❑ 空进程是不包含任何活跃组件的进程
① Activity
❑ Android程序的呈现层,显示可视化的用户界面,并接收与用户交互所产生的界面事件
❑ Android应用程序可以包含一个或多个Activity,一般需要指定一个程序启动时显示的Activity
② Service
❑ Service一般用于没有用户界面,但需要长时间在后台运行的应用
❑ 可公开Service的程序接口,供其他进程调用
③ Broadcase receiver
❑ 用来接收广播消息的组件,不包含任何用户界面
❑ 可以启动Activity或者Notification通知用户接收到重要信息
❑ Notification能够通过多种方法提示用户,包括闪动背景灯、震动设备、发出声音或在状态栏上放置一个图标
④ Content provider
❑ 是Android系统提供的一种标准的共享数据的机制,其他程序通过ContentProvider访问程序的私有数据
❑ Android系统内部提供一些内置的ContentProvider,能够为应用程序提供重要的数据信息(联系人信息,通话记录)
Activity生命周期指Activity从启动到销毁的过程
① 活动状态,Activity在用户界面中处于最上层,完全能被用户看到,能够与用户进行交互
② 暂停状态,Activity在界面上被部分遮挡,该Activity不再处于用户界面的最上层,且不能够与用户进行交互
③ 停止状态,Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡
④ 非活动状态,不在以上三种状态中的Activity则处于非活动状态
转换关系:当第一个Activity启动后,则Activity处于活动状态;如果启动新的Activity,部分遮挡先前的Activity,则先前的Activity转换为暂停状态;如果新启动的Activity完全遮挡了先前的Activity,则先前的Activity转换为停止状态;活动的Activity被用户关闭,或暂停状态或停止状态的Activity被系统终止后,都会转换成非活动状态。
作用:Activity事件回调函数具体分为Activity生命周期的事件回调函数和Activity状态保存和恢复函数的事件回调函数。
Activity生命周期的事件回调函数的作用主要是为了让Activity程序了解自身状态的变化;Activity状态保存和恢复函数的事件回调函数的作用主要是保存或恢复Activity的状态信息。
Activity事件的调用顺序:
(1)onCreate,完全生命周期开始,初始化Activity;
(2)onStart,可视生命周期开始,对用户界面进行必要的更改;
(3)onRestoreInstanceState,恢复onSaveLnstanceState保存的用户界面信息;
(4)onResume,活动生命周期开始,保存界面信息;
(5)onSaveInstanceState,在onResume后,保存界面信息;
(6)onRestart,重新进入可视生命周期前,载入界面所需要的更改信息;
(7)onPause,活动生命周期结束,保存持久地数据或释放占用的资源;
(8)onStop,可视生命周期结束,保存持久地数据或释放占用的资源;
(9)onDestory,完全生命周期结束,释放资源
1. 这是用来获取系统日志信息的工具,并可以显示在Eclipse集成开发环境中
2. [V]:详细(Verbose)信息 [D]:调试(Debug)信息
[I]:通告(Info)信息 [W]:警告(Warn)信息 [E] :错误(Error)信息
(级别从低到高)
3. 在Android调试的时候,首先需要引入 android.util.Log 包,然后使用 Log.v()、 Log.d()、 Log.i() 、Log.w() 和 Log.e()五个函数在程序中设置“日志点”
(注意小写)
TextView、EditText、Button、ImageButton、Checkbox、RadioButton、Spinner、ListView和TabHost
5.2 TextView和EditText
⭐因为EditText继承于TextView,所以EditText是一个具有编辑功能的TextView控件。
·fill_parent、match_parent:当前控件大小和父类一样
·wrap_parent:布局元素根据内容修改大小
·@+id/TextView01表示所设置的ID值,其中@表示后面的字符串是ID资源
·android_textSize:“200sp”(大小)、android_textColor=“#FF6666”(颜色)
android_layout_width/height…
5.6 界面事件
按键事件(KeyEvent) 将传递给 onKey()函数进行处理
触摸事件(TouchEvent)将传递给onTouch()函数进行处理
(1)选项菜单 是常用的Android系统菜单,可分为图标菜单和扩展菜单,图标菜单的子项最多是六个,支持显示图标,不支持单选框和复选框;而当子项多余六个时,采用扩展菜单,扩展菜单的子项是垂直排列,支持单选框和复选框,不支持显示图标。第一次启动选项菜单时,只需要调用一次onCreateMenu函数。
(2)子菜单 的表现形式是浮动窗体的形式,适应小屏幕的显示形式,能够展示更加详细的信息,通过addSubMenu函数增加子菜单,但不支持嵌套。在选项菜单和快捷菜单中使用子菜单,便于显示和分类相似的菜单子项。
(3)快捷菜单 采用动窗体的显示形式,启动方式特别,点击界面元素超过2秒后,则启动该界面元素的快捷菜单。每次启动快捷菜单时,都要调用一次onCreateMenu函数。
操作栏代替了传统的标题栏功能,右侧用来显示“选项菜单”的菜单项,但所显示的内容,会根据操作栏所具有的空间不同而具有不同的现实方式。在屏幕尺寸较小的设备上,操作栏会自动隐藏菜单项的文字,而仅显示菜单项的图标;而在屏幕尺寸较大的设备上,操作栏会同时显示菜单项的文字和图标。
操作栏提供多个实用的功能包括 (1)将“选项菜单”的菜单项显示在操作栏的右侧; (2)基于Fragment实现类似于Tab页的导航切换功能; (3)为导航提供可“拖拽—放置”的下拉列表; (4)可在操作栏上实现类似于“搜索框”的功能。
如果需要将子Activity的信息返回给父Activity,则可以使用Sub-Activity的方式去启动子Activity
(1)以Sub-Activity的方式启动子Activity
(2)设置子Activity的返回值
(3)在父Activity中获取返回值
Intent是一个动作的完整描述,包含了动作的产生组件、接收组件和传递的数据信息。Intent为Activity、Service和BroadcastReceiver等组件提供交互能力,将一个组件的数据和动作传递给另一个组件。Intent的一个最常见的用途就是启动Activity和Service;另一个用途是在Android系统上发布广播消息,广播消息可以是接收到特定数据或消息,也可以是手机的信号变化或电池的电量过低等信息。
Intent过滤器是一种根据Intent中的动作(Action)、类别(Categorie)和数据(Data)等内容,对适合接收该Intent的组件进行匹配和筛选的机制。Intent过滤器的作用是匹配数据类型、路径和协议,还包括可以用来确定多个匹配项顺序的优先级。每个Intent过滤器可以定义多个
(1)Android系统把所有应用程序包中的Intent过滤器集合在一起,形成一个完整的Intent过滤器列表;
(2)在Intent与Intent过滤器进行匹配时,Android系统会将列表中所有Intent过滤器的“动作”和“类别”与Intent进行匹配,没有指定“动作”的Intent过滤器可以匹配任何的Intent,但是没有指定“类别”的Intent过滤器只能匹配没有“类别”的Intent;
(3)把Intent数据Uri的每个子部与Intent过滤器的标签中的属性进行匹配;
(4)如果Intent过滤器的匹配结果多于一个,则可以根据在
❑ 通过调用Context.startService()启动Service,通过调用Context.stopService()或Service.stopSelf()停止Service。因此,Service一定是由其它的组件启动的,但停止过程可以通过其它组件或自身完成
❑ 在启动方式中,启动Service的组件不能够获取到Service的对象实例,因此无法调用Service中的任何函数,也不能够获取到Service中的任何状态和数据信息
❑ 能够以启动方式使用的Service,需具备自管理的能力,而且不需要从通过函数调用获取Service的功能和数据
❑ Service的使用是通过服务链接(Connection)实现的,服务链接能够获取Service的对象实例,因此绑定Service的组件可以调用Service中实现的函数,或直接获取Service中的状态和数据信息
❑ 使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接
❑ 如果在绑定过程中Service没有启动,Context.bindService()会自动启动Service,而且同一个Service可以绑定多个服务链接,这样可以同时为多个不同的组件提供服务
❑ 这两种使用方法并不是完全独立的,在某些情况下可以混合使用
❑ 以MP3播放器为例,在后台工作的Service通过Context.startService()启动某个音乐播放,但在播放过程中如果用户需要暂停音乐播放,则需要通过Context.bindService()获取服务链接和Service对象实例,进而通过调用Service对象实例中的函数暂停音乐播放过程,并保存相关信息
❑ 在这种情况下,如果调用Context.stopService()并不能够停止Service,需要在所有的服务链接关闭后,Service才能够真正的停止。
Service能够长期在后台运行,适用于无需用户干预,且规则或长期运行的后台功能。首先,因为Service没有用户界面,更加有利于降低系统资源的消耗,而且Service比Activity具有更高的优先级,因此在系统资源紧张时,Service不会被Android系统优先终止。即使Service被系统终止,在系统资源恢复后Service也将自动恢复运行状态,因此可以认为Service是在系统中永久运行的组件。Service除了可以实现后台服务功能,还可以用于进程间通信(InterProcessCommunication,IPC),解决不同Android应用程序进程之间的调用和通讯问题。
1. 接口
❑ 由SQLite C API组成,因此无论是应用程序、脚本,还是库文件,最终都是通过接口与SQLite交互
2. 编译器
❑ 在编译器中,分词器和分析器对SQL语句进行语法检查,然后把SQL语句转化为便于底层处理的分层数据结构,这种分层的数据结构称为“语法树”
❑ 然后把语法树传给代码生成器进行处理,生成一种用于SQLite的汇编代码,最后由虚拟机执行
3. 虚拟机
❑ SQLite数据库体系结构中最核心的部分是虚拟机,也称为虚拟数据库引擎(Virtual Database Engine,VDBE)
❑ 与Java虚拟机相似,虚拟数据库引擎用来解释并执行字节代码
❑ 虚拟数据库引擎的字节代码由128个操作码构成,这些操作码主要用以对数据库进行操作,每一条指令都可以完成特定的数据库操作,或以特定的方式处理栈的内容
4. 后端
❑ 后端由B-树、页缓存和操作系统接口构成,B-树和页缓存共同对数据进行管理
❑ B-树的主要功能就是索引,它维护着各个页面之间复杂的关系,便于快速找到所需数据
❑ 页缓存的主要作用是通过操作系统接口在B-树和磁盘之间传递页面
SQLite数据库的优势是其嵌入到使用它的应用程序中。这样不仅提高了运行效率,而且屏蔽了数据库使用和管理的复杂性,程序仅需要进行最基本的数据操作,其他操作可以交给进程内部的数据库引擎完成
<TextView android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView01">
<EditText android:id="@+id/EditText01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="EditText01">
<Button android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button01">
<ImageButton android:id="@+id/ImageButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@String/hello"/>
<CheckBox android:id="@+id/CheckBox01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox01">
<CheckBox android:id="@id/CheckBox02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox02">
<RadioGroup android:id="@+id/RadioGroup01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton android:id="@+id/RadioButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton01">
<RadioButton android:id="@+id/RadioButton02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton02">
<TextView android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="warp_content"
android:text="@string/hello"/>
<ListView android:id="@+id/ListView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名:" >
<EditText android:id="@+id/entry"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<Button android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确认">
<Button android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消" >
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/label"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="用户名:">
<EditText android:id="@+id/entry"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_below="@id/label">
<Button android:id="@+id/cancel"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dip"
android:layout_below="@id/entry"
android:text="取消" >
<Button android:id="@+id/ok"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_toLeftOf="@id/cancel"
android:layout_alignTop="@id/cancel“
android:text="确认">
1. final static int MENU_00 = Menu.FIRST;
2. final static int MENU_01 = Menu.FIRST+1;
3. final static int MENU_02 = Menu.FIRST+2;
4. final static int MENU_03 = Menu.FIRST+3;
5. final static int MENU_04 = Menu.FIRST+4;
6.
7. @Override
8. public boolean onCreateOptionsMenu(Menu menu) {
9. menu.add(0,MENU_00,0,"打印").setIcon(R.drawable.pic0);
10. menu.add(0,MENU_01,1,"新建").setIcon(R.drawable.pic1);
11. menu.add(0,MENU_02,2,"邮件").setIcon(R.drawable.pic2);
12. menu.add(0,MENU_03,3,"设置").setIcon(R.drawable.pic3);
13. menu.add(0,MENU_04,4,"订阅").setIcon(R.drawable.pic4);
14. return true;}
1. TextView textView = (TextView)findViewById(R.id.TextView01);
2. EditText editText = (EditText)findViewById(R.id.EditText01);
3. textView.setText("用户名:");
4. editText.setText("Rajan");
显示启动:
◼ 创建一个Intent
◼ 指定当前的应用程序上下文,以及要启动的Activity
◼ 把创建好的Intent作为参数传递给startActivity()方法
1. Intent intent = new Intent(IntentDemo.this, ActivityToStart.class);
2. startActivity(intent);
在AndroidManifest.xml文件中注册这两个Activity
1. <?xml version="1.0" encoding="utf-8"?>
2.
3. package="edu.hrbeu.IntentDemo"
4. android:versionCode="1"
5. android:versionName="1.0">
6.
7.
8. android:label="@string/app_name">
9.
10.
11.
12. -filter>
13.
14.
15. android:label="@string/app_name">
16.
17.
18.
19.
在IntentDemoActivity.java文件中,包含了使用Intent启动Activity的核心代码:
1. Button button = (Button)findViewById(R.id.btn);
2. button.setOnClickListener(new OnClickListener(){
3. public void onClick(View view){
4. Intent intent = new Intent(IntentDemoActivity.this, NewActivity.class);
5. startActivity(intent);
6. }
7. });
隐式启动:
1. Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com"));
2. startActivity(intent);
WebViewIntentDemo示例说明了如何隐式启动Activity
1. String urlString = editText.getText().toString();
2. Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlString));
3. startActivity(intent);
获取子Activity的返回值,一般分为三个步骤:
❑ 以Sub-Activity的方式启动子Activity
❑ 设置子Activity的返回值
❑ 在父Activity中获取返回值
startActivityForResult(Intent, requestCode)函数,参数Intent用于决定启动哪个Activity,参数Intent用于决定启动哪个Activity,requestCode是请求码。因为所有子Activity返回时,父Activity都调用相同的处理函数,因此父Activity使用requestCode来确定数据是哪一个子Activity返回的。
显式启动子Activity的代码如下:
int SUBACTIVITY1 = 1;
Intent intent = new Intent(this, SubActivity1.class);
startActivityForResult(intent, SUBACTIVITY1);
隐式启动子Activity的代码如下:
int SUBACTIVITY2 = 2;
Uri uri = Uri.parse("content://contacts/people");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(intent, SUBACTIVITY2);
在子Activity中设置返回值:
Uri data = Uri.parse("tel:" + tel_number);
Intent result = new Intent(null, data);
result.putExtra("address", "JD Street");
setResult(RESULT_OK, result);
finish();
在父Activity中处理子Activity的返回值:
当子Activity关闭后,父Activity会调用onActivityResult()函数,用了获取子Activity的返回值。
public void onActivityResult(int requestCode, int resultCode, Intent data)
private static final int SUBACTIVITY1 = 1;
private static final int SUBACTIVITY2 = 2;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
Super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case SUBACTIVITY1:
if (resultCode == Activity.RESULT_OK){
Uri uriData = data.getData();
}else if (resultCode == Activity.RESULT_CANCEL){
}
break;
case SUBACTIVITY2:
if (resultCode == Activity.RESULT_OK){
Uri uriData = data.getData();
}
break;
}
}
显式启动:
1 final Intent serviceIntent = new Intent(this, RandomService.class);
2 startService(serviceIntent);
隐式启动(声明Intent-fliter的action属性)
1
2
3
4
5
隐式启动(设置Intent的action属性,这样则可以在不声明Service所在类的情况下启动服务)
1 final Intent serviceIntent = new Intent();
2 serviceIntent.setAction("edu.hrbeu.RandomService");
停止服务
stopService(serviceIntent);
OnBind()
1 public class MathService extends Service{
2 private final IBinder mBinder = new LocalBinder();
3
4 public class LocalBinder extends Binder{
5 MathService getService() {
6 return MathService.this;
7 }
8 }
9
10 @Override
11 public IBinder onBind(Intent intent) {
12 return mBinder;
13 }
14 }
在AndroidManifest.xml文件中注册Activity
1. <?xml version="1.0" encoding="utf-8"?>
2.
3. package="edu.hrbeu.IntentDemo"
4. android:versionCode="1"
5. android:versionName="1.0">
6.
7.
8. android:label="@string/app_name">
9.
10.
11.
12. -filter>
13.
14.
15. android:label="@string/app_name">
16.
17.
18.
19.
AndroidManifest.xml文件中注册Service
1
(书P164最上面)
在ActivityManagerService处理广播,当广播为有序广播时,将静态广播接收器和动态广播接收器合并起来,形成最终的有序广播接收顺序。
上述的规则1排序为:
1. 优先级高的先接收
2. 同优先级的动静态广播接收器,动态优先于静态
3. 同优先级的动态广播接收器 或者同优先级的静态广播接收器,按照图1 的流程注册顺序。
即静态:先扫描的大于后扫描的,动态:先注册的大于后注册的。
当广播为普通广播时,规则2排序为:
1. 无视优先级,动态广播接收器优先于静态广播接收器
2. 同规则1排序的第3点