Android 组件篇

Android 四大组件详解

        Android平台下四个核心组件分别是提供界面的Activity组件、提供后台计算的Service组件、提供广播接收的Broadcast Receiver组件、提供数据共享的Context Provider组件。不同组件具有不同的特性以及各自的声明周期,下面就来对每个组件进行详细的分析。

 1.Activity组件

        (1)Activity组件概述

                Activity是最常见的一种Android组件,每个Activity都相当于一个屏幕,其为用户提供了进行交互的可视界面。应用程序可以根据需要包含一个或多个Activity,这些Activity一般都继承自android.app包下的Activity类,并且这些Activity之间的运行是相互独立的。

        (2)Activity组件生命周期的3个阶段。

                1)运行态(running state)

                        此时Activity显示在屏幕前台,并且具有焦点,可以和用户的操作进行交互。

               2)暂停态(paused state)

                       此时Activity失去焦点,并被其它的运行态Activity取代在屏幕前台显示,暂停态的Activity仍然保留其状态和成员等其它信息,当系统的内存非常匮乏时,暂停态的Activity会被结束掉以获得更多的资源。

               3)停止态(stopped state)

               停止态的Activity不仅没有焦点,而且是完全不可见的,虽然其也保留状态和成员等信息,停止态的Activity会在系统需要的时候被结束。

        (3)Activity组件要点

                当Activity在不同的状态之间切换时,可以通过重写相应的回调方法来编写状态改变时应该执行的动作。

                Activity之间通过Intent进行通信。

                android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity

        (4)Activity组件类图

              

        (5)Activity的加载模式

                Activity共有4中加载模式:standard、singleTop、singleTask和singleInstance。

                1)standard加载模式

                        standard加载模式是Activity的默认加载模式,在加载时会创建一个新的Activity的实例,类似于调用startActivity方法时设置Intent的标志位Intent.FLAG_ACTIVITY_NEW_TASK。

                2)singleTop加载模式

                        singleTop加载模式表示当前Activity的实例处于前台并可视时,该实例会收到发送过来的Intent消息。

                3)singleTask加载模式

                        singleTask加载模式表示当前Activity栈(Task)中当前Activity实例运行时,该实例会收到相应的Intent消息,接收方法类似于singleTop加载模式。

                4)singleInstance加载模式

                         singleInstance加载模式表示该Activity以单子模式加载,在当前Activity栈中唯一,接收方法类似于singleTop加载模式。

        (6)Activity的属性配置

                1)配置变化属性

                        android:mcc属性表示MCC,即SIM卡中存储的IMSI号中的国家代码部分,当发生国际漫游时,该属性配置会发生变化。

                        android:mnc属性表示MNC,即SIM卡中存储的IMSI号中的网络代码部分,当发生不用运营商网络间漫游时,该配置会发生变化。

                        android:locale属性表示当前显示的语言发生变化。

                        android:touchscreen属性表示触摸屏发生了变化,考虑当当前的实际情况,只有在支持多屏显示时才需要使用该属性。

                        android:keyboard属性表示键盘类型发生了变化,如外接蓝牙键盘等。

                        android:keyboardHidden属性表示显示或者隐藏键盘,对翻盖、滑盖终端有效。

                        android:navigation属性表示导航键发生了变化,如从轨道变化为五向键,考虑到当前的实际情况,该配置显然不会发生变化。

                        android:orientation属性表示屏幕方向,当前重力传感器几乎已经成为智能终端标配的情况下,需对该配置多加注意。

                        android:screenLayout属性表示屏幕布局发生变化。在不支持多屏显示的情况下,该配置不会发生变化。

                        android:fontScale属性表示字体发生了变化。

                        android:uiMode属性表示UI模式发生了变化,如变为车载模式、夜间模式等。

                2)屏幕旋转属性

                        android:screenOrientation属性是Activity的一个重要属性,在有重力传感器的情况下,开发者必须考虑屏幕的适配情况。其属性值包括unspecified、landscape、portrait、user、behind、sensor和nosensor等。其中unspecified为默认值,旋转策略有系统决定;langscape表示横屏;portrait表示竖屏;user表示当前用户倾向的屏幕方向;behind表示屏幕方向和Activity栈中当前Activity下面的Activity相同;sensor表示根据重力传感器确定屏幕方向,这是一个重要的属性值;nosensor表示忽略传感器方向。

                3)主题属性

                        android:thene属性表示当前Activity的主题。这是一个非常重要的属性,通常用于设置标题栏、状态栏等,当然也可以设置开发者自定义的主题

                        该属性的设置方法: android:theme=”@android:style/Theme.NoTitleBar“

                4)启动约束属性

                        android:exported属性表示启动约束,即是否允许被其他进程调用,如果值为fase,则该Activity仅可被同一应用中的组件或拥有相应用户ID的应用的组件调用;如果值为true,则允许被其他进程调用。

                        android:exported属性的默认值与携带的Intent过滤器有关,如果没有携带任何Intent过滤器,则其值为false,否则为true。

2.Service组件

        (1)Service组件概述

                Service没有提供与用户进行交互的表示层。Service是运行在后台的一种Android组件,当应用程序需要进行某种不需要前台显示的计算或数据处理时,就可以启动一个Service来完成,每个Service都继承自android.app包下的Service类。

               Service一般由Activity或其他Context对象来启动,当启动Service之后,该Service将会在后台运行,即使启动这个Service得Activity或其他组件的生命周期已经结束,Service仍然会继续运行,直到自己的生命周期结束为止。每个Service都应该在AndroidMainfest.xml中进行声明。

        (2)Service组件的运行方式

               服务的运行有两种方式,即绑定服务和启动服务。

               1)通过startService方法启动

                       以启动服务的方式运行服务时,服务并不会随着绑定组件的销毁而销毁,而是服务会自我销毁,这种方式适用于文件加载、文件上传等请求后自行运行的场景。

                       当系统调用startService方法时,如果该Service还未启动,则依次调用其onCreate方法和onStart方法来启动。当其他Context对象调用stopService方法、Service调用自称的stopSelf或stopService方法时才会停止Service的执行。

               2)通过bindService方法启动

                       当通过绑定服务的方式运行服务时,一旦绑定解除,服务即被销毁,当进行多次绑定时,只有所有的绑定均解除,服务才会销毁。

                       当系统调用bindService方法时,如果该Service未启动,则会调用其onCreate方法完成初始化工作,然后会将该Service和Context对象(如Activity)进行绑定,当被绑定的Context对象被销毁时,与之绑在一起的Service也会停止运行。

                       解除绑定时unbindService。

                       绑定服务时需要设置ServiceConection和标志位,ServiceConnection可以监控服务的状态,在进行服务绑定时,其标志位可以为BIND_AUTO_CREATE、BIND_DEBUG_UNBING和BIND_NOT_FOREGROUND等。

                       BIND_AUTO_CREATE表示当接收到绑定请求时,如果服务尚未创建,则即刻创建,在系统内存不足,需要销毁优先级组件来释放内存,且只有驻留该服务的进程成为被销毁对象时,服务才可被销毁。

                       BIND_DEBUG_UNBIND通常用于调试场景中判断绑定的服务是否正确,但其会引起内存泄露,因此非调试目的的不建议使用。

                       BIND_NOT_FOREGROUND表示系统将阻止驻留该服务的进程具有前台优先级,仅在后台运行,该标志位在Froyo引入。

                       绑定服务时以异步的方式运行的。绑定服务必须在当前的上下文环境中进行,在某些场景中,如果无法绑定成功,则可能需要在应用级的上下文环境中进行。

                      

        (3)Service组件要点

               需要注意的是,尽管存在两种方式启动Service,但是无论Service是通过什么方式启动的,都可以将其与Context对象进行绑定。

        (4)Service组件类图

             

        (5)服务生命周期流程图

               

 

3.Broadcast Receiver组件

        (1)Broadcast Receiver组件概述

                Broadcast Receiver也不提供与用户交互的表示层,其是一种负责接收广播消息并对消息作出反应的组件。在Android的系统中就存在许多这样的广播,比如电池电量过低或信号过低时,系统就会发出广播进行通知。广播的发送本质上是基于Intent进行的。

               应用程序如果需要响应某个广播消息,应该注册对应的BroadcastReceiver对象,该对象继承自BroadcastReceiver类,该类位于Android.content包下。

        (2)Broadcast Receiver组件广播方式

               1)BroadcastReceiver发布广播的方式

                       发布一个广播比较容易,在需要的地方创建一个Intent对象,将信息的内容和用于过滤的信息封装起来,通过调用Context.sendBroadcast方法、Context.sendOrderedBroadcast方法或者Context.sendStickyBroadcast方法将该Intent对象广播出去,发布广播方式的区别如下。

                       通常,使用sendBroadcast或sendStickyBroadcast发送出去的Intent,所有满足条件的BroadcastReceiver都会执行其onReceive方法。但若有多个满足条件的BroadcastReceiver,其执行onReceive方法的顺序是没有保证的。

                       而通过sendOederedBroadcast方法发送出去的Intent,会根据BroadcastReceiver注册时IntentFilter设置的优先级的顺序来执行onReceive方法,相同优先级的BroadcastReceiver执行onReceiver方法的顺序是没有保证的。

                       sendStickyBroadcast主要的不同是,Intent在发送后会一直存在,并且在以后调用registerReceiver注册相匹配的Receiver时会把这个Intent对象直接返回给新注册的Receiver。

               2)BroadcastReceiver接收广播的方式

                       发布的广播实体是Intent,那么接收广播的时候就需要通过IntentFilter对象来进行过滤。BroadcastReceiver的生命周期比较简单,只有一个回调方法--onReceive,该方法在应用程序接收到发给自己广播时候调用,所以BroadcastReceiver的使用方法也相对简单,只需要对onReceive方法进行合理重写,在适当的地方注册该Broadcast Receiver即可。

                       在AndroidMainfest.xml文件中声明。注册信息包含在<receiver></receiver>标签中,并在<intent-filter>标签内设定过滤规则。

                        在代码中创建并设置IntentFilter对象。该IntentFilter对象包含了对广播的过滤规则,然后再需要的地方调用Context.registerReceiver方法和Context.unregisterReceiver方法进行注册和取消注册,如果采用这种方式注册,当Context对象被销毁时,该BroadcastReceiver也就不复存在了。

4.Context Provider组件

        (1)Context Provider组件概述

                 Context Provider和其它的应用程序组件有很大的不用,Context Provider主要用于不用的应用程序之间进行数据共享。在Android平台下,每个应用程序都有独立的内存空间,如果某个应用程序需要使用其它应用程序的数据,就必须采用ContextProvider对象。

        (2)Context Provider组件要点

                每个ContextProvider都继承自Android.context包下的ContextProvider类,其功能就是提供自己的数据给外部应用程序使用,提供的数据可以存储为Android文件、SQLite数据库文件或其他合法的格式。

                ContextProvider提供数据及访问数据的接口,真正访问数据的是ContextResolver对象,该对象可以与ContextProvider对象进行通信,以达到共享数据的目的。 

5.Intent组件

        (1)Intent组件概述

                Intent是Android用于进程内或进程间通信的机制,其底层的通信以Binder机制实现,在物理层上则以共享内存的方式来实现。

        (2)Intent的应用场景

                Intent主要用于两种场景:广播和发起意图,其属性有ComponentName、action、data、category、extras、flags等。在进行Intent的匹配时,需要匹配Action、data、category等3个属性。

                1)ComponentName

                        ComponentName为处理Intent消息的Android组件,可以是Activity、服务等。通过调用setClassName方法设置。

                2)action

                        action表示Intent的类型,可以是查看、删除、发布或其他,最常使用的就是android.intent.action.MAIN。android.intent.action.MAIN表示一个应用程序的入口,通常和android.intent.category.LAUNCHER联合使用。

                3)data

                        data表示Intent携带的数据,通常和MIME类型联合使用。

                4)category

                        category表示Intent的策略,目前常用的几个Category:android.intent.category.DEFAULT、android.intent.category.LAUNCHER、android.intent.category.MONKEY、android.intent.category.OPENABLE、android.intent.category.BROWSABLE。

                        对于隐式Intent,如果创建Intent时没有指明category属性,则系统会默认设置其属性为android.intent.category.DEFAULT,这时如果在Intent过滤器中没有指明category属性为android.intent.category.DEFAULT,则会造成匹配失败。

                5)Extras

                        Extras表示Intent的附加信息,它在组件间传递消息时非常有用。目前Extras可以支持多种数据类型,如布尔型、整形、字符串等。

                6)Flags

                        Flags表示Intent的标志位,经常用于Activity的场景中。Flags和Activity的启动模式有密切的关系。

        (3)特殊应用场景

                作为整个系统的灵魂组件,Intent功能之强大和使用范围之广,下面介绍Intent应用的一些特殊场景,如开启自启动、网络监视、获取内容、SD挂载等。

                1)开机自启动

                        接收开机自启动事件的Intent过滤器的设置方法如下。

                        <receiver android:name=".receiver.ImServiceAutoStarter"  android:process="android.process.im">

                                <intent-filter>

                                        <action android:name="android.intent.action.BOOT_COMPLETED"/>

                                </intent-filter>

                        </receiver>

                2)网络监听

                        在基于网络的应用已非常普及的今天,监听网络的状态变化已是一种必备的功能,其Intent过滤器的设置方法如下。

                        <intent-filter>

                                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

                        <intent-filter>

                3)获取内容

                        为了响应获取内容的事件,必须在Intent过滤器中设置action属性为android.intent.action.GET_CONTENT,设置category属性为android.intent.category.DEFAULT.

                4)返回桌面

                        为了返回桌面,需要设置category属性为Intent.CATEGORY_HOME

        (4)Intent的分类

                从目的地(ComponentName)的明确性来划分,Intent分显式Intent和隐式Intent。

                所谓显式Intent,即明确指明了目的地、不需要系统进行Intent匹配的Intent,在应用程序内部进行组件调用时,应首选显式Intent。

                所谓隐式Intent,即没有明确指定目的地、需要系统根据自己的信息进行匹配的Intent。这类Intent同样用于应用间的相互调用,有助于降低应用间的耦合性。

                PendingIntent仅是对Intent的一个封装,它使开发者能够更方便地操作Activity、服务、广播等。

        (5)PendingIntent的逻辑

                PendingIntent和Intent略有不同,其可设定执行次数,主要用于远程服务通信、闹钟、通知、短信、启动器中国,一般的应用很少采用。

                1)PendingIntent标志位

                         FLAG_ONE_SHOT表示返回的PendingIntent仅能执行一次,执行完成后即自动取消。

                         FLAG_NO_CREATE表示如果描述的PendingIntent不存在,并不创建相应的PendingIntent,而是返回NULL。

                         FLAG_CANCEL_CURRENT表示如果相应的PendingIntent已经存在,则取消前者,然后创建新的PendingIntent,者有利于保持数据为最新的,可用于即时通讯的通知场景。

                        FLAG_UPDATE_CURRENT表示更新PengdingIntent。

6.应用框架解析

        除了基本的组件外,为了维护整个UI系统的良好运行,在应用层,Android还设计了诸多的框架来进行相关方面的管理。本机主要介绍Service框架、Activity管理机制、Broadcast机制、对话框框架、标题栏框架、状态栏框架、通知机制和ActionBar框架等。

        (1)Service框架

                 作为执行应用后台运算和框架层运算的基本组件,服务扮演着十分重要的角色。根据通信的方式和应用场景,服务有不同的类型,具体而言,从通信的方式来看,服务科分为两种类型,即本地服务和远程服务,其中远程服务根据通信的方式又可分为基本AIDL的服务和基于Message的服务两种。从应用的场景来看,服务可以分为应用服务和系统服务等。

        (2)Activity管理机制

                Android的管理是通过Activity栈和Task来进行的。

                1)Activity栈

                        Android的管理主要是通过Activity栈来进行的。当一个Activity启动时,系统根据其配置或调用的方式,将Activity压入一个特定的栈中,系统处于运行(Running or Resumed)状态。当按Back键或触发finish方法时,Activity会从栈中被压出,进而被销毁,当有新的Activity压入栈时,如果原Activity依然可见,则原Activity的状态将转变为暂停(Paused)状态,如果原Activity完全被遮挡,那么其状态将转变为停止(Stoped)。

                2)Task

                        一个Task对应于一个Activity栈,Task是根据用户体验组成的运行期逻辑单元,Task中的Activity可以由不同的应用组成。

                        在实际的终端使用中,在主界面长按Home键弹出的一个网格界面即时当前运行的Task而非应用。

                        android:allowTaskReparenting属性用来配置是否允许Activity从启动它的Task移动到该Activity设置的Task亲和性相同的Task中。

                        android:alwaysRetainTaskState属性用于配置是否保留Activity所在的Task状态,默认为false。

                        android:clearTaskOnLaunch属性用于配置当Task从主界面重新启动时,是否需要清除除根Activity外的所有Activity,默认为false。

                        android:finishOnTaskLaunch属性用于配置当Task从主界面重新启动时,特定的Activity是否需要被销毁,默认为false。

                        android:taskAffinity属性用于配置启动Activity时运行在特定的Task中。只有在启动Activity的时候设置FLAG_ACTIVITY_NEW_TASK标志位才有效。

                3)Activity生命周期

                       

 

                        onResume()方法和很多初学者所认为的不同,其除了在Activity恢复可见性时被调用外,在构建Activity后也会被调用。另外,应避免直接调用onDestroy销毁Activity,争取销毁Activity的方式是调用finish方法。

        (3)Broadcast机制

                当特定时间发生时,需要通知到相应的模块,若受众不明确或较多,则需要进行广播。广播涉及顺序广播、无序广播、广播接收器。

                1)顺序广播

                         当广播需要以类似消息链的方式进行时,应采用顺序广播,顺序广播的接收器可以抛弃或继续传递消息。

                2)无序广播

                        无序广播是异步的,广播接收器除了接收广播外,无法对无序广播的行为产生影响。

                3)广播接收器

                        为了接收广播,开发者必须在AndroidMainfest.xml中配置广播接收器或通过Java实现广播接收器。

        (4)对话框框架

                目前提供了4中方式来创建对话框,分别为AlertDialog、ProgressDialog、DataPickerDialog、TimePickerDialog。其中AlertDialog是最通用的对话框形式,ProcessDialog用于描述进度信息,而DataPickerDialog和TimePickerDialog则主要用于日期和时间场景中。

               

                 1)AlertDialog对话框

                        AlertDialog是最常用的对话框,由标题、图标、按钮和呈现具体信息的视图组成,在默认情况下,通常setMessage可以设置显示的文本信息,通过setView可以加载开发自定义的视图。

                        如果希望创建一个对话框,则需通过AlertDialog.Builder进行。在onCreateDialog中创建对话框,通过showDialog显示对话框。通过dismissDialog隐藏对话框,如果尚没有显示对话框,调用dismissDialog会发生异常。

                        通过调用setCancelable可以使弹出不希望被用户取消的对话框,适用于所有对话框。

                        由于Dialog管理机制的问题,Dialog具备记忆能力,在需要数据更新的场景中,在onPrepareDialog方法进行数据更新。

                        由于无法在对话框中记忆对话框状态,dismissDialog方法必须和showDialog成对出现,若无showDialog与之配对,则会发生异常。

                2)ProgressDialog对话框

                        ProgressDialog通常用于耗时的操作,以免长时间无反应给用户造成一种系统假死的假象。

                        对于长时间运算的任务,应将ProgressDialog放在主线程之外执行,否则极易出现Android ANR消息。

                        ProgressDialog支持两种风格的进度显示,一种是进度条,一种是环形转动。这两种进度显示对应的风格分别为ProgressDialog.STYLE_HORIZONTAL和ProgessDialog.STYLE_SPINNER。默认的风格为ProgressDialog.STYLE_SPINNER。

                3)DatePickerDialog对话框

                        DatePickerDialog(日期对话框)时一个专用的对话框,其创建方式非常简单,在创建时,通常需要设置初始年、月、日和监控日期变化的回调函数。

                4)TimePickerDialog对话框

                        TimePickerDialog(时间对话框)和DatePickerDialog相似,TimePickerDialog在创建时需要设置初始时间和监控时间变化的回调函数。

        (5)标题栏框架

                Android中的标题栏具有传统标题栏更丰富的功能,其除了可标识当前界面的主题外,还支持进度显示,允许用户隐藏、自定义标题栏。目前Android标题栏支持FEATURE_NO_TITLE、FEATURE_PROGRESS、FEATRUE_CUSTOM_TITLE等多种定制。

                1)隐藏标题栏

                        通过配置AndroidManifest.xml隐藏标题栏的方法:<activityandroid:name-"LunarLander"  android:theme="@android:style/Theme.NoTitleBar">

                        通过代码实现隐藏标题栏的方法:requestWindowFeatrue(android.view.window.FEATURE_NO_TITLE)。

                 2)自定义标题栏

                         Android提供了自定义标题栏的方法,标题栏的FEATURE_CUSTOM_TITLE不能和FEATURE_LEFT_ICON、FEATURE_NO_TITLE等同时使用。

                         设置标题栏的方法:requestWindowFeature(window.FEATURE_CUSTOM_TITLE);getWindow().setFeatureInt(window.FEATURE_CUSTOM_TITLE,R.layout.custom_title_1);

                 3)进度显示

                         支持两种明确进度显示,一种是主进度,一种是辅进度,辅进度在本地应用中较少使用。在网络环境中,如在进行流媒体播放时,可以用主进度表示播放进度,用辅进度标识下载进度。

                 4)图标显示

                        Android的标题栏实际上由标题、进度条、左图标和右图标构成。

        (6)状态栏框架

                和传统终端的状态栏一样,Android状态栏同样提供了电量信息、蜂窝信息、SMS、MMS、邮件、WIFI信号、蓝牙信号、闹钟等状态信息。另外,状态栏还提供了应用安装、数据下载等职能终端特有的状态信息。除此之外,状态栏还承担着通知栏的功能,使用户能以最少的操作查看收到的信息。

                

 

                  在状态栏中,起主要作用的时StatusBarPolicy,它承担着接收系统发来的Intent消息、更新状态显示的功能,它是服务StatusBarMangerService的客户端。

                  整个状态栏框架是通过StatusBarService来实现的,在StatusBarService初始化时初始化了一个用于显示statusbar的StatusBarView。在StatusBarView中定义了状态栏的实现布局,而具体的布局文件时在framewoeks\base\packages\systemui\res\layout\status_bar.xml中实现的。

                1)状态栏的隐藏

                        通过AndroidMainfest.xml设置全屏的方法:

                        <activity android:name="GActivity"

                                android:them="@android:style/Theme.Black.NoTitleBar.Fullscreen">

                        </activity>

                        通过Java设置全屏的方法:

                        getWindow().setFlags(WindowManger.LayoutParams.FLAG_FULLSCREEN,WindowManger.LayoutParames.FLAG_FUIISCREEN);

                        requestWindowFeature(Window.FEATURE_NO_TITLE);        //隐藏标题栏

                        通过Java实现动态隐藏和显示状态栏

                        getWindow().addFlag(WindowManger.LayoutParame.FLAG_FULLSCREEN);   //隐藏

                        getWindow().clearFlags(WindowManager,LayoutParame.FALG_FULLSCREEN);        //显示

                2)电量信息

                        当StatusBarPolicy收到Action为ACTION_BATTERY_CHANGED的Intent时,StatusBarPolicy会通知StatusBarManger进行电量图标的更新。

                        StatusBarPolicy还能相应Action为ACTION_BATTERY_LOW、ACTION_BATTERY_OKAY、ACTION_POWER_CONNECTED的Intent。

                3)蜂窝信息

                        对蜂窝协议的支持十分充分,目前内置的支持包括GSM、UMTS、CDMA、4G等。

                4)WIFI信号

                        对于WIFI信号,可以相应Action为WifiManger.NETWORK_STATE_CHANGED_ACTION、WifiManger.WIFI_STATE_CHANGED_ACTION、WifiManger.RSSI_CHANGED_ACTION的Intent。

                 5)蓝牙信号

                         对于蓝牙信号,Android目前可以相应BluetoothAdapter、BluetoothHeadset、BluetoothA2dp和BluetoothPbap的状态变化。

                 6)闹钟

                         当StatusBarPolicy收到Action为ACTION_ALERM_CHANGED的Intent时,StatusBarPolicy会通知StatusBarManager进行闹钟图标的更新。

        (7)通知机制

                 Android提供了多种方式来向用户反馈状态信息,主要包括Toast提醒、通知栏提醒、对话框提醒等,其中Toast提醒通常用于页面的提示,通知栏提醒通常用于交互事件的通知,一般非常重要的提醒都已对话框的形式给出。

                 对于需要用户相应的事件,可以通过对话框的方式通知用户给予必要的反馈。

                 Toast和Notification均由框架层的NotificationManagerService维护。

                 1)Toast

                         Toast通常不用于交互,可以被创建于Activity和Service中,在默认情况下,Toast仅支持文本提示。

                         Toast提醒的显示时间较短。目前系统支持两种显示时间:LENGTH_SHORT和LENGTH_LONG。其中,LNEGTH_SHORT表示显示时间为2s,LENGTH_LONG表示显示时间为3.5s。

                         在默认情况下,Toast显示在屏幕的正下方,水平居中。对于特殊场景,Toast允许自定义显示的位置。

                         如果简单的文本信息无法满足开发者的需要,还可以利用Toast支持的自定义视图。

                         Toast不能再AsyncTask的doInBackground方法中运行,如果希望实现类似的效果,可以在Handler中进行处理。

                2)Notifcation

                        Notifcation更适合于交互事件的通知,常用于短消息、即时消息、下载、外围设备的状态变化等场景中。

                        Notifcation支持文字显示、振动、三色灯、振铃音等多种提示形式,在默认情况下,Notifcation仅显示消息标题、消息内容、时间等3项内容。

                        1)Notification管理

                                  Android通过表示符来管理Notification,发起一个Notification的方法:notificationManager.notify(notifictionId, mNotification);

                                  取消Notification的方法很多,如果希望用户单击后Notification即被清除,则相应方法: notification.flags |= FALG_AUTO_CANCEL

                                  如果希望手动清除某项Notification,相应方法:mNotificationMgr.cancel(LOW_MEMORY_MOTIFICATION_ID);

                                  如果希望清除所有Notification时,相应方法:mNotification.cancelAll();

                        2)振动提醒

                                 Android通过Notification还提供了振动提醒,通常用于比较紧迫的场景。

                                 振动方式为:延迟0ms,然后振动700ms,在延迟500ms,接着振动1000ms。相应方法:Notification n=new Notification();        n.vibrate=new long[]{0, 700, 500, 1000};        mNM.notify(1, n);

                                 如果设置为默认振动方法,相应方法: notification.defaults |= Notification.DEFAULT_VIBRATE。

                        3)三色灯提醒

                                 Android支持三色灯提醒,开发者可以根据不同的场景选择点亮不同颜色的灯。需要注意的是,只要设置Notification的标志位为FLAG_SHOW_LIGHTS,才能支持三色灯提醒。

                                 创建三色灯提醒的Notification:Notification n=new Notification();        n.flags |= Notification.FLAG_SHOW_LIGHTS;        n.ledAREGB=0xff0000ff;        n.ledOnMS = 300;        n.ledOffMS = 300;        mNM.notify(1,n);

                                 如果希望设置默认三色灯提醒,相应方法:notification.defaults |= Notification.DEFAULT_LIGHTS;

                         4)振铃音提醒

                                 Notification支持默认振铃音、自定义振铃音、Android多媒体数据库等多种提醒方法。

                                 默认振铃音:notification.default |= Notification.DEFAULT_SOUND;

                                 自定义振铃音:notification.sound=Uri.parse(file:///sdcard/notification/ringer.mps);

                                 基于Android多媒体数据库提醒方式:notification.sound=Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");

                         5)提醒标志位

                                 FLAG_SHOW_LIGHTS                         //三色灯提醒

                                 FLAG_ONGOING_EVENT                   //发起事件

                                 FLAG_INSISTENT                                //振铃音将持续到Notification取消或Notification窗口打开

                                 FLAG_ONLY_ALERT_ONCE              //发起Notification后,振铃音或振动均执行一次

                                 FLAG_AUTO_CANCEL                       //用户单击后自动消失

                                 FLAG_NO_CLEAT                               //只有全部清除时,Notification才会清除

                                 FLAG_FOREGROUND_SERVICE      //表示正运行的服务

        (8)搜索框架

                通过框架层提供的搜索管理器(Search Manager),Android管理者搜索对话框并为用户传递搜索关键字。

                实现搜索需要完成以下步骤:实现搜索配置文件,实现显示搜索结果的Activity,实现执行搜索的算法,发起搜索。

        (9)ActionBar框架

                ActionBar取代了状态栏和标题栏的位置,可以帮组开发者尽可能地利用空间。通过ActionBar还可以设置自定义的视图,即ActionView,其本质上是菜单的一种实现。

                在ActionBar中,应用图标对单击事件的相应是通过onOptionsItemSelected方法进行的,其对应的ID为android.R.id.home。ActionBar通常需要和Fragment交互。

                1)隐藏Actionbar

                         通过Androidmanifest.xml设置Activity的theme属性可以隐藏ActionBar,方法如下:

                         <activity android:theme="@android:style/Theme.Holo.NoActionBar">

                         当需要动态的隐藏ActionBar时,只能通过Java代码的方式实现,方法如下:

                         ActionBar actionBar=getActionBar();

                         actionBar.hide();

                         重新显示ActionBar的方法:

                         actionBar.show();

                2)Action项管理

                         Action项本质上是一种特殊的菜单项,由图标和文字两部分组成,考虑到用户体验,在实际开发中,不建议设置超过2个的Action项。Action项有4种属性可以配置。

                         SHOW_AS_ACTION_ALWAYS                //总是作为Action项显示

                         SHOW_AS_ACTION_IF_ROOM               //空间足够时显示

                         SHOW_AS_ACTION_NEVER                   //永远不作为Action项显示

                         SHOW_AS_ACTION_WITH_TEXT           //显示Action项的文字部分

                3)ActionView

                        ActionView即所谓的在ActionBar上出现的Widget,用于实现一些快捷的操作,并充分利用ActionBar的空间。ActionView的实现由两种方式:加载布局文件和加载视图类。无论是加载布局文件还是加载视图类,均可通过配置文件实现。

                4)添加Tab页

                        ActionBar可以显示Tab页,在Activity中进行Fragment间切换。每个Tab可以包含的元素有标题和图标,类似于TabWidget。向ActionBar中添加Tab页的步骤为:

                        创建ActionBar.TabListenter,并实现其方法。

                        设置ActionBar的导航模式为NAVIGATION_MODE_TABS.

                        创建Tab页。

                        添加Tab页。 

                        在导航模式下Tab页的实现和TabActivity的实现有很大的区别,虽然两者切换Tab均是基于FrameLayout实现的,但前者需要开发者做更多的工作。

                5)下拉菜单

                        基于ActionBar还能实现下拉菜单的功能。下拉菜单主要是基于SpinnerAdapter来处理数据的。实现下拉菜单的步骤如下:

                        设置导航模式。

                        实现并加载资源文件。

                        创建并设置OnNavigationListion。

7.Activity类控件

                   

        (1)ListActivity控件

                1)ListActivity控件概述

                        ListActivity可以用来实现列表功能。在android中,ListActivity提供了对基本的单行、双行列表的封装,同时支持自定义列表。自定义列表主要是基于ListView来实现的,为了方便起见,在此一并介绍。

                2)ListActivity控件实现步骤

                        实现一个列表包括3步:选择或自定义列表项布局文件、实现适配器并加载数据、为ListActivity设置适配器。

                3)ListView布局文件

                        <ListView  android:id="@+id/android:list" />   <TextView  android:id="@+id/android:empty"  android:text="no data" /> 当ListView没有数据显示时,TextView显示出来,同时ListView会被影藏(只有在ListActivity中才有此效果,在Activity中必须自行设置)。

                基于单行布局的simple_list_item_1布局文件、基于简单双行布局的simple_list_item_2布局文件、基于单行单选布局的simple_list_item_single_choice布局文件、基于单行多选布局的simple_list_item_multiple_choice布局文件、类似树状图的simple_expandable_list_item_1/simple_expandable_list_item_2布局文件等。

        (2)PreferenceActivity控件

                1)PreferenceActivity控件概述

                        PreferenceActivity主要用于实现偏好设置,在布局上PreferenceActivity以PreferenceCreen为根布局,支持CheckBoxPreference等多种形式的偏好设置,这些偏好值默认存储于应用的SharePreference中,通过getSharedPreference可以获取SharedPreferences对象,通过Preference.OnPreferenceChangeListener监听器可以监听到偏好值得变化。

                2)CheckBoxPreference控件

                        提供了进行二选一偏好的方法,还支持偏好的说明。

                3)DialogPreference控件

                        DialgPreference仅作为一个借口存在,如果借助DialogPreference实现更加复杂的偏好必须继承DialogPreference。

                4)EditTextPreference控件

                        提供支持输入框的偏好设置的功能,通过getEditText方法可以获得输入框的内容,通过getText方法可以获得SharedPreference中存储的偏好值,通过setText方法可以将偏好值保存在SharedPreferences中。

                5)ListPreference控件

                        当某个偏好有多个偏好值可选时,ListPreference就派上用场了,在使用ListPreference是需要注意entries和entryValue属性,其中entries表示界面的内容,而entryValue对应的是实际偏好值。

                6)RingtonePreference控件

                        用于设置铃声的特殊偏好控件,目前Android提供的铃声类型包括ringtong、notification、alarm和all等。其中all表示所有可用的铃声。

               7)PreferenceCategory控件

                         提供了偏好组的功能。

        3)TabActivity控件

                 1)TabActivity控件概述

                        能够让用户在单一界面实现更多的功能,简化用户的操作。

                        TabActivity的根布局控件为TabHost,他由TabWidget和通常基于FrameLayout的内容显示区域组成。

8.适配器

       

        (1)适配器类型

                目前Android支持两种类型的适配器:基本适配器(BaseAdapter)和游标适配器(CursorAdapter)。基本适配器是最通用的适配器,游标适配器是用来适配数据库的数据流的,其他的系统级适配器都是继承自这两种适配器。

        (2)BaseAdapter适配器

                BaseAdapter适配器是基本的适配器,是其他适配器的基类。实际开发中会调用BaseAdapter的子类或通过BaseAdapter自定义适配器来实现视图与数据的适配功能。

        (3)ArrayAdapter适配器

                在默认情况下,ArrayAdapter假定整个布局文件为一个TextView,只有指定了mFiledId,ArrayAdapter才认为加载了一个自定义布局。ArrayAdapter的实现有很强的局限性,仅能显示单行的列表。

        (4)SimpleCursorAdapter适配器

                在SimpleCursorAdapter的初始化和setViewBinder的实现过程中指定了布局文件、游标、数据项、控件ID等,但是没有处理布局加载和数据绑定,在bindView的实现中处理了布局加载和数据绑定。

                从bindView的实现中可以看出,ViewBinder实际上是用户的一个自定义实现接口,当用户没有进行自定义实现时,会通过传递的控件数量进行默认数据绑定。

                支持图片加载,不过这时通过游标获取的不再是文本数据,而是图片的URL。

                在进行普通数据库数据加载时比较复杂的场景也可以利用SimpleCursorAdapter而非自定义适配器来实现。当默认数据绑定无法满足需求时,可以使用ViewBinder。

        (5)适配器处理流程

               

                在BaseAdapter适配器中,应用了设计模式的观察者模式(Observer Pattern),当数据源发生变化时,可以通知显示控件自行刷新。

                通过分析,AdapterDataSetObserver是AdapterView的一个私有类,在开发者为ListView设置适配器时,ListView会通过适配器注册观察器,当开发者调用适配器的notifyDataSetChanged方法时,ListView会收到数据源变化的通知,进行自行刷新。

                在数据库适配器中数据发生变化时,应重新获取游标(Cursor),然后在调用notifyDataSetChanged方法进行数据刷新。

        (6)自定义适配器

                1)基于BaseAdapter的自定义适配器

                        对于基于BaseAdapter的自定义适配器,需要重点关注getView=方法的实现,getView方法完成的主要工作是列表项布局文件的加载和数据的绑定。需要注意的是,只有convertView为空时加载布局文件,这样可以避免无谓的性能损耗,这是优化ListView显示的一个重要方法。

                2)基于CursorAdapter的自定义适配器

                        基于CursorAdapter的自定义适配器的实现重点在于bingView方法和newView方法。其中bingView方法用于绑定数据,newView方法用于加载布局文件。

                        考虑到加载列表项时多次操作findViewById方法,对性能有所影响,因此在Android中设计ViewHolder,以其来进行优化。通过View的setTag方法和getTag方法可大幅度提高显示速率,这样是优化ListView显示的一种重要方法。

9.Service类组件

       

        (1)InputMethodService

                提供输入法的标准实现普通开发者不必关心这一点。一种输入法的界面由3部分组成,即软输入视图(Soft Input View)、候选视图(Candidates View)和全屏模式(Fullscreen Mode)。

        (2)IntentService

                IntentService作为Service的子类,主要用于处理异步请求,防止服务阻塞。所有的请求将在一个工作线程(HandleThread)中处理,工作结束后,xianc也结束。

        (3)MediaScannerService

                MediaScannerService主要在设备启动和SD卡挂载时执行多媒体文件的扫描工作。出于性能方面的考虑,Android区分SD卡和手机存储空间。

                对于SD卡,会在收到Action为ACTION_MEDIA_MOUNTED的Intent(即SD卡挂载)时进行扫描。

                对于手机存储空间,会在收到Action为ACTION_BOOT_COMPLETED的Intent(即设备启动完毕)时进行烧苗。另外在下载文件时,也可能启动媒体扫描服务。

        (4)RecognitionService

               RecognitionService是一个抽象服务,仅在开发者希望实现一个新的语音识别器时才可能用到。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值