420 likes | 661 Views
第四章 Android 开发框架. 本章主要内容. Android 系统架构. Android 系统架构. Android. 操作系统. 中间件. 应用程序. 上层. 底层. 函数库 (Library). 虚拟机 (Virtual Machine; VM). 应用程序框架 (Application Framework). Android 系统架构. 1. 应用程序层 (Applications).
E N D
Android系统架构 Android 操作系统 中间件 应用程序 上层 底层 函数库(Library) 虚拟机(Virtual Machine; VM) 应用程序框架(Application Framework)
Android系统架构 1.应用程序层(Applications) Android会同一系列核心应用程序包一起发布,主要包括拨号程序、email客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的这些应用程序都是使用JAVA语言编写的。
Android系统架构 2、应用程序框架层(Application Framework) 支撑应用程序正常运行的是一系列的服务, 其中包括: • Views System:丰富且可扩展的视图(Views),用于构建应用程序。 • Content Providers(内容提供器):使得应用程序可以访问由另一个应用程序所维护的数据(如联系人数据库), 或者共享它们自己的数据。 • Resource Manager(资源管理器):提供非代码资源的访问。 • Notification Manager(通知管理器):使应用程序可以在系统状态栏中显示提示信息。。 • Activity Manager(Activity管理):用于管理应用程序各Activity的生命周期并提供常用的导航回退功能。
Android系统架构 3、函数库层(Libraries) Android 包含的一些核心库: • System C library:一个从 BSD 继承来的标准 C 系统函数库( libc ), 它是专门为基于embedded linux的设备定制的。 • Media Libraries:基于PacketVideoOpenCORE;该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括MPEG4、H.264、MP3、AAC、AMR、JPG、PNG等等 。 • Surface Manager:提供对显示子系统的管理,并且为应用程序提供了2D和3D图层的无缝融合。
Android系统架构 3、函数库层(Libraries) • LibWebCore:一个最新的web浏览器引擎,支持Android浏览器及可嵌入应用程序的web视图。 • SGL:底层的2D图形引擎。 • 3D Libraries:基于OpenGL ES 1.0 APIs实现;该库可以使用硬件 3D加速(如果可用)或者使用高度优化的3D软加速。 • Free Type:位图(bitmap)和矢量(vector)字体显示。 • SQLite:SQLite是一套开放源码的关系数据库,是一种对于所有应用程序可用并且功能强劲的轻型关系型数据库引擎。 • SSL:Secure Socket Layer用于保护网页通讯安全的协议。
Android系统架构 • 4、Android运行时环境(Android Runtime) Android虽然使用Java程序语言来开发应用程序,但是却采用Android自有的Android Runtime来执行。 Android Runtime由下面两个核心部分组成。 • Core Libraries 即核心库,该核心库实现了JAVA编程语言核心库的大多数功能。 • Dalvik Virtual Machine(DalvikVM,Dalvik虚拟机)
Android系统架构 • 5、内核层(Linux Kernel) Android平台的系统内核是Linux 2.6,其包含的主要功能有安全(Security)、内存管理(Memory Management)、进程管理(Process Managemen)、网络协议栈(Network Stack)、硬件驱动(Driver Model)等,Linux内核同时也作为硬件和软件栈之间的抽象层。
Android应用程序组成 一个常规的Android程序主要由Activity、Broadcast Receiver、Service、Content Provider四个部分组成。但是并不是所有的Android应用程序都必须包含这4个部分
Android应用程序组成 • Activity 在Android程序中,一个Activity就相当于手机屏幕的一页显示,类似于浏览器的一个网页。 在一个Android应用程序中,可能涉及多个Activity,并在这几个Activity中进行跳转。打开一个新的Activity时会将当前的Activity置为暂停状态并压入堆栈。
Android应用程序组成 • Broadcast Receiver 可以翻译为“广播接收器”,它用于对Android系统广播的事件进行接收以方便做出所需的处理。 需要注意的是BroadcastReceiver本身并不会生成UI,即对于用户这个接收事件是不可见的,BroadcastReceiver通过NotificationManager来通知用户。BroadcastReceiver可以在AndroidManifest.xml中注册,也可以在代码中通过Context.registerReceiver()进行动态注册。
Android应用程序组成 • Service Service没有用户界面,是一种可以运行很长时间的程序。可以简单地将Service理解为没有用户界面的Activity。 Service可以通过两种方式启动,即startService(Intent service)和Context.bindService(),在第5章中会对Service进行详细的介绍。
Android应用程序组成 • Content Provider 在Android中,无论是文件数据还是数据库数据,这些数据都是私有的,默认不对其他应用程序开放的。可以将Content Provider理解为数据操作类。在该类中,Android实现了一组标准的方法接口,通过这些接口,应用程序就可以读取或者保存这个类提供的各种类型的数据了。 常见的接口 • query(Uri,String[],String,String[],String),该方法通过关键字查询数据 ; • insert(Uri,ContentValues),该方法的作用是将一条数据插入到指定位置; • update(Uri,ContentValues,String,String[]),更新数据; • delete(Uri,String,String[]),删除数据。
Activity生命周期 一个Activity有三个基本的状态: • 当其在前台运行时(即在Activity当前任务的堆栈顶),即为活动状态(运行状态)。 • 当Activity失去焦点但是对用户仍然可见时为paused暂停状态。一个暂停的Activity仍然是处于活动状态的。 • 如果一个Activity完全被另一个Activity所掩盖,那它的状态会变为stopped。此时仍然保存着状态信息。 • 当其他应用程序需要使用更多的内存时,系统有可能会杀死处于paused状态或stopped状态的Activity。
Activity生命周期 如图所示是描述Activity生命周期的框图
Activity生命周期 • Activity生命周期,包括了三个主要的循环结构,由大至小分别如下: • 完整的Activity生命周期。这个周期循环从该Activity的onCreate()方法第一次被调用开始,直到onDestroy()方法被调用结束。 • Activity的可见生命周期。这个周期从onStart()方法被调用时开始,直到onStop()方法被调用时结束,在这个周期中Activity对于用户是可见的,但是也有可能不处于Activity栈的最上方即不是可交互的。 • Activity前台生命周期。在这个周期中Activity始终处于栈的顶端并且可以与用户交互。
Activity生命周期 Activity类的实现: publicclass Activity extendsApplicationContext { protectedvoidonCreate(Bundle savedInstanceState); protectedvoidonStart(); protectedvoidonRestart(); protectedvoidonResume(); protectedvoidonPause(); protectedvoidonStop(); protectedvoidonDestroy(); }
Android项目架构 src:存放java源代码。 gen:编译器自动生成的java代码,这个目录下的文件是由系统维护的。 assets:这个目录下的文件会被打包到Android应用程序安装包(.apk)中。 res: 资源文件目录,添加到这个目录下的文件都会在gen下的R.java文件中与一个整形常量相关联;如果在res下存放的资源在应用中没有被使用,在打包的时候就不会将这部分资源打包,这样可以减小安装文件的大小。 drawable-hdpi:存放适用于高分辨率设备的图片文件。
Android项目架构 drawable-ldpi: 存放适用于低分辨率设备的图片文件。 drawable-mdpi:存放适用于中等分辨率设备的图片文件。 layout:这个目录下的文件是用于自定义界面的。 values:这个目录下用于存放一些常量,例如最常见的string.xml文件是用于存放程序中的字符串,只要在这些文件中增加了任何的属性配置,都会反映在gen下的R.xml文件中。 AndroidManifest.xml :应用程序功能清单文件,用于向系统描述该应用程序的一些功能,例如该应用程序包含了多少个Activity、Service,需要使用哪些权限等等 default.properties: 这个文件不会直接使用,由编译工具自动生成。 proguard.cfg:该文件也不重要,适用于对代码进行加密,防止被反编译。
AndroidManifest.xml文件解析 AndroidManifest.xml是每个Android项目中必须的文件。它位于项目的根目录,描述了package中的全局数据,包括package中的组件(如Activities,Services等等)以及这些组件各自的实现类,还有各种能被处理的数据即其他属性。 属性——intent-filters 这些filters隐式地描述了其对应的Activity启动的条件。除了声明程序中的Activities,Content Providers,Services,和Intent Receivers组件之外,permissions和instrumentation(安全控制和测试)也需要在文件中进行声明。
AndroidManifest.xml文件解析 一个简单的AndroidManifest.xml文件示例,取自于HelloWorld: <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.android.HelloWorld"android:versionCode="1" android:versionName="1.0"> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".HelloWorld" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
AndroidManifest.xml文件解析 下面介绍一下AndroidMainfest.xml所提供的部分标签: • 1.manifest 根节点,描述package的所有信息。 2.uses-permission 请求package正常工作所需被赋予的安全许可。该节点可出现0~n次。 3.permission 声明安全许可来限制其他程序访问package中的组件和功能,这种许可权限是指自身package对外部发放的权限。该节点可出现0~n次。 4.instrumentation 声明用于测试此package的其他类或包。该节点可出现0~n次。 5.application 包含package中application级别组件声明的节点。该节点只允许出现0或1次。 6.activity Activity是用来与用户交互的主要工具。所有需要使用到的Activity都必须声明在各自的activity标签中。
AndroidManifest.xml文件解析 • 7.intent-filter 该节点声明了所属组件所支持的Intent类型。通常在此标签下会包含随后的action(至少包含一个)、category、data类型等标签。 8.action——组件支持的action类型。 9.category——组件支持的category类型。 10.type——组件支持的Intentdata MIME type。 11.schema——组件支持的Intentdata URI scheme。 12.authority——组件支持的Intentdata URI authority。 13.path——组件支持的Intentdata URI path。 14.receiver IntentReceiver使得application能够获知数据的改变和发生的操作,并且可以允许application当前不在运行状态。通常配合<intent-filter>使用。 15.service Service是能在后台运行组件。通常配合<intent-filter>使用 16.provider ContentProvider是用来管理持久化数据并发布给其他应用程序使用的组件。
三大组件间通信—Intent Intent 的作用 Android应用程序的三大核心组件——activity、service和broadcast receiver之间通过Intent消息机制来交互。 Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯。比如说调用startActivity()来启动一个activity,或者由broadcaseIntent()来传递给所有感兴趣的BroadcaseReceiver, 再或者由startService()/bindservice()来启动一个后台的service. 所以可以看出来,intent主要是用来启动其他的activity 或者service,所以可以将intent理解成activity之间的粘合剂。
三大组件间通信—Intent Intent 的构成 • 要在不同的activity之间传递数据,就要在intent中包含相应的东西,一般来说数据中最基本的应该包括: • Action——用来指明要实施的动作是什么,比如说ACTION_VIEW, ACTION_EDIT等。具体的可以查阅android SDK-> reference中的Android.content.intent类,里面的constants中定义了所有的action。 • Data——要事实的具体的数据,一般由一个Uri变量来表示 • 下面是简单的例子: • ACTION_VIEWcontent://contacts/1//显示identifier为1的联系人的信息。 • ACTION_DIAL content://contacts/1//给这个联系人打电话
三大组件间通信—Intent Intent 的构成 • intent还包括一些其他的元素: • Category(类别): 这个选项指定了将要执行的这个action的其他一些额外的信息,例如 LAUNCHER_CATEGORY 表示Intent 的接受者应该在Launcher中作为顶级应用出现;而ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。 • Type(数据类型): 显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定。 • Component(组件): 指定Intent的的目标组件的 类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。 • Extras(附加信息),是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。
三大组件间通信—Intent Intent 的解析 应用程序组件为了告诉Android自己能响应、处理哪些隐式Intent请求,可以声明一个甚至多个Intent Filter。每个Intent Filter描述该组件所能响应Intent请求的能力——组件希望接收什么类型的请求行为,什么类型的请求数据。比如在需要请求网页浏览器时,网页浏览器程序的Intent Filter就应该声明它所希望接收的Intent Action是WEB_SEARCH_ACTION,以及与之相关的请求数据是网页地址URI格式。如何为组件声明自己的Intent Filter? 常见的方法是在AndroidManifest.xml文件中用属性< Intent-Filter>描述组件的Intent Filter。 Intent可以分为两大类,显式Intent(Explicit Intents)和Intent Filter即隐式Intent(Implicit Intents),一般来说显式Intent主要用于应用程序内部的组件之间传递消息,而隐式Intent则用于多个应用程序之间的交互。Intent Filter进行匹配时的三要素是Intent的动作、数据以及类别。实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目标组件。接下来我们讲解这三方面检查的具体规则。
三大组件间通信—Intent 1.Action匹配 < intent-filter>元素中可以包括子元素< action>,比如: < intent-filter> < action android:name=”com.example.project.SHOW_CURRENT” /> < action android:name=”com.example.project.SHOW_RECENT” /> < action android:name=”com.example.project.SHOW_PENDING” /> < /intent-filter> 一条< intent-filter>元素至少应该包含一个< action>,否则任何Intent请求都不能和该< intent-filter>匹配。如果Intent请求的Action和< intent-filter>中个某一条< action>匹配,那么该Intent就通过了这条< intent-filter>的匹配。如果Intent请求或< intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。 (1) 如果< intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条< intent- filter>匹配; (2) 反之,如果Intent请求中没有设定Action类型,那么只要< intent-filter>中包含有Action类型,这个 Intent请求就将顺利地通过< intent-filter>的匹配。 2.类别匹配 < intent-filter>元素可以包含< category>子元素,比如: < intent-filter . . . > < category android:name=”android.Intent.Category.DEFAULT” /> < category android:name=”android.Intent.Category.BROWSABLE” /> < /intent-filter> 当Intent请求中所有的Category与组件中某一个IntentFilter的< category>完全匹配时,该Intent请求将成功匹配,IntentFilter中多余的< category>声明并不会导致匹配失败。一个没有指定任何类别匹配的IntentFilter仅仅只会匹配没有设置类别的Intent请求。 Intent 的解析
三大组件间通信—Intent Intent 的解析 3.数据匹配 数据在< intent-filter>中的描述如下: < intent-filter . . . > < data android:type=”video/mpeg” android:scheme=”http” . . . /> < data android:type=”audio/mpeg” android:scheme=”http” . . . /> < /intent-filter> 元素指定了希望接受的Intent请求的数据URI和数据类型,URI被分成三部分来进行匹配:scheme、 authority和path。其中,用setData()设定的Inteat请求的URI数据类型和scheme必须与IntentFilter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要相匹配才会成功匹配。
三大组件间通信—Intent Intent 的实例解析 Intent示例一 创建一个Intent的代码如下所示。 Intent i = new Intent(Intent.ACTION_DIAL,Uri.parse(”tel://13800138000″)); 创建好Intent之后,就可以通过它告诉Android希望启动新的Activity了。 startActivity(i); Activity启动后显示界面如图。
三大组件间通信—Intent Intent 的实例解析 Intent示例二 创建一个Intent的代码如下所示。 Intent intent = new Intent(Intent.ACTION_EDIT, null); startActivity(intent); 执行此代码的时候,系统就会在程序主配置文件AndroidMainfest.xml中寻找 <action android:name="android.intent.action.EDIT" />对应的Activity,如果对应为多个activity具有<action android:name="android.intent.action.EDIT" />此时就会弹出一个dailog选择Activity,显示界面如图。
三大组件间通信—Intent Intent 的实例解析 Intent示例三 利用Intent在Activity之间传递数据 在MainActivity中执行如下代码: Bundle bundle = new Bundle(); bundle.putStringArray("NAMEARR", nameArr); Intent intent = new Intent(MainActivity.this, SubActivity.class); intent.putExtras(bundle); startActivity(intent); 在SubActivity中,代码如下: Bundle bundle = this.getIntent().getExtras(); String[] arrName = bundle.getStringArray("NAMEARR"); 以上代码就实现了Activity之间的数据传递!
三大组件间通信—Intent 点击拨号后,调用系统的拨号程序,最终实现拨号 选择简单拨号程序,出现输入框填写电话号码,并拨号, 按绿色拨号按钮,呼出一个菜单选择使用拨号程序。 Intent 的实例解析 简单的拨打电话实例——项目名称PhoneCallDemo
三大组件间通信—Intent Intent 的实例解析 publicclassMainTinyDialextends Activity { /** Called when the activity is first created. */ @Override publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 按照main.xml來渲染用戶界面 setContentView(R.layout.main); // 找到存放电话号码的可编辑文本框 finalEditTextPhoneNumberEditText = (EditText) findViewById(R.id.PhoneNumberEditText); // 找到拨号按钮 Button button = (Button) findViewById(R.id.Button01); // 为拨号按钮设置一个点击事件观察者 button.setOnClickListener(newButton.OnClickListener() { //实现监听器接口的匿名内部类,其中监听器本身是View类的内部接口 //实现接口必须实现的onClick方法 @Override publicvoidonClick(View v) { // 获得可编辑文本框中的值,也就是电话号码 String phoneNumber = PhoneNumberEditText.getText().toString(); // new Intent(行为,数据),其中action_dial是拨号行为,数据是电话号码 Intent intent = new Intent(Intent.ACTION_DIAL, Uri .parse("tel://" + phoneNumber)); // 去调用那些可以处理拨号行为的Activity startActivity(intent); } }); } }
xml简介 xml的全称Extensible Markup Language,即可扩展标记语言。xml是一种简单的数据存储语言,它使用一系列简单的标记对数据进行描述,是internet环境中跨平台、依赖于内容的技术,也是当前结构化信息文档的处理的有效工具。 xml是简单的数据存储语言,它相对于专业的数据库(如:Access,Oracle,SQL Server等)具有局限性。相对而言数据库提供了更为有效的数据存储和数据分析能力(如:数据排序,查找等),xml则仅仅是对数据进行展示。
Android生命周期 Android的一个非常重要的特点就在于它对生命周期的控制。Android生命周期的控制并不是直接由应用程序本身来控制,而是通过系统与应用程序联合来进行控制的。这样系统就可以知道哪些应用程序正在运行,哪些对用户来说更加重要,以及目前系统的可用内存是多大等等信息。 对于开发者而言,理解各种不同的应用程序组件(特别是Activity,Service和IntentReceiver)及它们在应用程序进程的生命周期中所起到的作用是十分重要的。一个使用不当的应用组件会导致系统kill掉该应用的进程。
Android生命周期 在内存不足时由系统决定哪些进程被Kill掉,Android的方法就是将所有进程放入一个基于组件的运行与状态的“重要性层级”中。以下是重要性的排序: • foreground process(显著进程)持有一个与用户交互的屏幕顶层的Activity,或者一个目前正在运行的IntentReceiver。 • visible process(可见进程)持有一个用户在屏幕上可见的但并不是最显著位置的Activity(onPause() 方法被调用)。 • service process(服务进程)持有一个通过startService() 方法启动的Service。 • background process(后台进程) 持有一个用户已不可见的Activity(onStop() 方法被调用)。 • empty process(空进程)不包含任何应用程序组件。
本章小结 这一章主要介绍了Android的一些基本的概念,对Android的架构有了一定的了解,这对后面的编程有促进的作用,只有弄明白了原理,才能编写出更好的程序。