1 / 26

第二章 Android 应用程序

第二章 Android 应用程序. 本章学习目标:. 了解 Android 基本组件 了解 Android 生命周期 掌握 Android 程序调试. 2.1 基本组件介绍.

Télécharger la présentation

第二章 Android 应用程序

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第二章 Android应用程序

  2. 本章学习目标: • 了解Android基本组件 • 了解Android生命周期 • 掌握Android程序调试

  3. 2.1 基本组件介绍 • Android应用程序由组件组成,组件是可以被调用的基本功能模块。Android系统利用组件实现程序内部或程序间的模块调用,以解决代码复用的问题,这是Android系统非常重要的特性。在程序设计时,在AndroidManifest.xml中声明可共享的组件,声明后其他应用程序可以直接调用这些共享组件。Android系统有4个重要的组件,分别是Activity、Service、BroadcaseReceiver和ContentProvider。

  4. 2.1 基本组件介绍 • Activity是Android中最常用的组件,是应用程序的表示层,Activity一般通过View来实现应用程序的用户界面,相当与一个屏幕,用户与程序的交互是通过该类实现的。Android应用程序可以包含一个或多个Activity,一般在程序启动后会呈现一个Activity,用于提示用户程序已经正常启动。Activity在界面上的表现形式一般是全体窗体,也可以是非全屏悬浮窗体或对话框。 • Service一般用于没有用户界面,但需要长时间在后台运行的应用。实际上,Service是一个具有较长的生命周期但是并没有用户界面的程序。例如在播放MP3音乐时,使用Service播放MP3音乐,可以在关闭播放器界面的情况下长时间播放MP3音乐,并通过对外公开Service的通信接口,控制MP3音乐播放的启动、暂停和停止。

  5. 2.1 基本组件介绍 • Service一般由Activity启动,但是并不依赖于Activity,即当Activity的生命周期结束时,Service仍然会继续运行,直到自己的生命周期结束为止。Service的启动方式有两种。startService方式启动是当Activity调用startService方法启动Service时,会依次调用onCreate和onStart方法来启动Service,而当调用stopService方法结束Service时,又会调用onDestroy方法结束Service。Service同样可以在自身调用stopSelf或stopService方法来结束Service。bindService 方式启动是Activity调用bindService方法启动Service,此时会依次调用onCreate和onBind方法启动Service。而当通过unbindService方法结束Service时,则会依次调用onUnbind和onDestroy方法。

  6. 2.1 基本组件介绍 • BroadcastReceiver为用户接收广播通知的组件,当系统或某个应用程序发送广播时,可以使用BroadcastReceiver组件来接收广播信息并做相应处理。在信息发送时,需要将信息封装后添加到一个Intent对象中,然后通过调用Content.sendBroadcast()、sendOrderedBroadcast()或sendStickyBroadcast()方法将Intent对象广播出去,然后接收者会检查注册的IntentFilter是否与收到的Intent相同,当相同时便会调用onReceive()方法来接收信息。三个发送方法的不同之处是使用sendBroadcast()或者sendStickyBroadcast()方法发送广播时,所有满足条件的接收者会随时地执行,而使用sendOrderedBroadcast()方法发送的广播接受者会根据IntentFilter中设置的优先级顺序来执行。

  7. 2.1 基本组件介绍 • BroadcastReceiver的使用过程如下: 1、将需要广播的消息封装到Intent中。 2、然后通过三种发送方法中的一种将Intent广播出去。 3、通过IntentFilter对象来过滤所发送的实体Intent。 4、实现一个重写了onReceive方法的BroadcastReceiver。 • 需要注意的是,注册BroadcastReceiver对象的方式有两种,一种是在AndroidManifest.xml中声明,另一种是在Java代码中设置。在AndroidManifest.xml中声明时,将注册的信息包裹在<receiver></receiver>标签中,并通过<intent-filter>标签来设置过滤条件;在Java代码中设置时,需要先创建IntentFilter对象,并为IntentFilter对象设置Intent的过滤条件,并通过Content.registerReceiver方法来注册监听,然后通过Content.unregisterReceiver方法来取消监听

  8. 2.1 基本组件介绍 • ContentProvider是用来实现应用程序之间数据共享的类。当需要进行数据共享时,一般利用ContentProvider为需要共享的数据定义一个URI,然后其他应用程序通过Content获得ContentResolver并将数据的URI传入即可。Android系统已经为一些常用的数据创建了ContentProvider,这些ContentProvider都位于android.provider下,只要有相应的权限,自己开发的应用程序便可以轻松地访问这些数据。 • 对于ContentProvider最重要的就是数据模型(data model)和URI,接下来分别对其进行介绍。数据模型就是ContentProvider为所有需要共享的数据创建一个数据表,在表中,每一行表示一条记录,而每一列代表某个数据,并且其中每一条数据记录都包含一个名为“_ID”的字段类标识每条数据。URI就是每个ContentProvider都会对外提供一个公开的URI来标识自己的数据集,当管理多个数据集时,将会为每个数据集分配一个独立的URI,所有的URI都以“content://”开头。需要注意的是,使用ContentProvider访问共享资源时,需要为应用程序添加适当的权限才可以。权限为“<uses-permission.android:name=”android.permission.READ_CONTACTS”/>”。

  9. 2.2 Activity生命周期 • Activity生命周期指Activity从启动到销毁的过程,在这个过程中,Activity一般表现为4种状态,分别是活动状态、暂停状态、停止状态和非活动状态。活动状态是指当Activity在用户界面中处于最上层,用户完全看得到,能够与用户进行交互,则这时Activity处于活动状态;暂停状态是指当Activity在界面上被部分遮挡,该Activity不再处于用户界面的最上层,且不能够与用户进行交互,则这个Activity处于暂停状态;停止状态是指Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡,则这个Activity处于停止状态;非活动状态是指Activity所处的不在以上三种状态中的另一种状态。

  10. 2.2 Activity生命周期 • Activity启动后处于活动状态,此时的Activity处于最上层,是与用户正在进行交互的组件,因此Android系统会努力保证处于活动状态Activity的资源需求,资源紧张时可终止其他状态的Activity;如果用户启动了新的Activity,部分遮挡了当前的Activity,或新的Activity是半透明的,则当前的Activity转换为暂停状态,Android系统仅在为处于活动状态的Activity释放资源时才终止处于暂停状态的Activity;如果用户启动新的Activity完全遮挡了当前的Activity,则当前的Activity转变为停止状态,停止状态的Activity将优先被终止;活动状态的Activity被用户关闭后,或暂停状态或停止状态的Activity被系统终止后,Activity便进入了非活动状态。

  11. 2.2 Activity生命周期 • 图2-1 Activity状态变换图

  12. 2.2 Activity生命周期 • 为能够更好地理解Activity的生命周期,还需要对Activity栈做一个简要的介绍。Activity栈保存了已经启动且没有终止的所有Activity,并遵循“后进先出”的原则。如图2-2所示,栈顶的Activity处于活动状态,除栈顶以外的其他Activity处于暂停状态或停止状态,而被终止的Activity或已经出栈的Activity的则不在栈内。 • Activity的状态与其在Activity栈的位置有着密切的关系,不仅如此,Android系统在资源不足时,也是通过Activity栈来选择哪些Activity是可以被终止的。一般来讲,Android系统会优先选终止处于停止状态,且位置靠近栈底的Activity,因为这些Activity启动顺序最靠前,而且在界面上用户是看不到的。

  13. 2.2 Activity生命周期 • 图2-2 Activity栈图

  14. 2.2 Activity生命周期 • 随着用户在界面的操作和Android系统对资源的管理,Android不断变化在Activity栈的位置,其状态也不断在四种状态中转变。为了能够让Android程序了解自身状态的变化,Android系统提供了多个事件回调函数,在事件回调函数中添加相关代码,就可以在Activity状态变化时完成适当的工作。下面的代码给出了Activity的主要事件回调函数。 • public class MyActivity extends Activity { • protected void onCreate(Bundle savedInstanceState); • protected void onStart(); • protected void onRestart(); • protected void onResume(); • protected void onPause(); • protected void onStop(); • protected void onDestroy(); }

  15. 2.2 Activity生命周期 • 表2-1 Activity生命周期的事件回调函数表

  16. 2.2 Activity生命周期 • 除了Activity生命周期的事件回调函数以外,还有onRestoreInstanceState()和onSaveInstanceState()两个函数经常会被使用,用于保存和恢复Activity的状态信息,例如用户在界面中选择的内容或输入的数据等。这两个函数不是生命周期的事件回调函数,不会因为Activity的状态变化而被调用,但在下述情况下会被调用:Android系统因为资源紧张需要终止某个Activity,但这个Activity在未来的某一时刻还会显示在屏幕上。 • 表2-2 Activity状态保存/恢复的事件回调函数说明表

  17. 2.2 Activity生命周期 • 图2-3 Activity事件回调函数的调用顺序图

  18. 2.2 Activity生命周期 • 全生命周期是从Activity建立到销毁的全部过程,始于onCreante(),结束于onDestroy()。一般情况下,使用者在onCreate()中初始化Activity所能使用的全局资源和状态,并在onDestroy()中释放这些资源。例如,Activity中使用后台线程下载网络数据,则在onCreate()中创建线程,在onDestroy()中停止并销毁线程。在一些极端的情况下,Android系统会不调用onDestroy()函数,而直接终止进程。 • 可视化生命周期是Activity在界面上从可见到不可见的过程,开始于onStart(),结束于onStop()。onStart()一般用来初始化或启动与更新界面相关的资源。onStop()一般用来暂停或停止一切与更新用户界面相关的线程、计时器和服务,因为在调用onStop()后,Activity对用户不再可见,更新用户界面也就没有任何实际意义。onRestart()函数在onStart()前被调用,用来在Activity从不可见变为可见的过程中,进行一些特定的处理过程。因为Activity不断从可见变为不可见,再从不可见变为可见,所以onStart()和onStop()会被多次调用。另外,onStart()和onStop()也经常被用来注册和注销BroadcastReceive,例如使用者可以在onStart()注册一个BroadcastReceive,用来监视某些重要的广播信息,并使用这些消息更新用户界面中的相关内容,并可以在onStop()中注销BroadcastReceive。

  19. 2.2 Activity生命周期 • 活动生命周期是Activity在屏幕的最上层,并能够与用户交互的阶段,开始于onResume(),结束于onPause()。例如,在手机进入休眠状态时,处于活动生命周期的Activity会调用onPause(),当手机从休眠状态被唤醒后,则会调用onResume()。因为在Activity的状态变换过程中onResume()和onPause()经常被调用,因此这两个函数中应使用更为简单、高效的代码。 • 函数调用顺序为:onCreate() → onStart()→ onResume() → onPause()→ onStop()→ onDestroy()。在Activity启动时,系统首先调用调用onCreate()函数分配资源,然后调用onStart()将Activity显示在屏幕上,之后调用onResume()获取屏幕焦点,使Activity能接受用户的输入,这时用户能够正常使用这个Android程序了。用户单击“回退键”或Activity调用finish()函数时,会导致Activity关闭,系统会相继调用onPause()、onStop()和onDestroy(),释放资源并销毁进程。因为Activity关闭后,除非用户重新启动应用程序,否则这个Activity不会出现在屏幕上,因此系统直接调用onDestroy()销毁了进程,且没有调用onSaveInstanceState()函数来保存Activity状态。

  20. 2.2 Activity生命周期 • 从可视化生命周期的函数调用顺序为:onSaveInstanceState ()→ onPause()→ onStop() → onRestart()→ onStart()→ onResume()。Activity启动后,当内置的拨号程序被启动时,原有的Activity被完全覆盖,系统首先调用onSaveInstanceState()函数保存Activity状态,因为界面上不可见的Activity可能被系统终止;系统然后调用onPause()和onStop(),停止对不可见Activity的更新。在用户关闭拨号程序后,系统调用onRestart()恢复需要界面上需要更新的信息,然后调用onStart()和onResume()重新显示Activity,并接受用户交互。系统调用了onSaveInstanceState ()保存Activity的状态,因为进程没有被终止,所以没有调用onRestoreInstanceState()恢复保存的Activity状态。

  21. 2.2 Activity生命周期 • 为了分析活动生命周期中的函数调用顺序,首先启动ActivityLifeCycle,然后通过“挂断键”使模拟器进入休眠状态,然后再通过“挂断键”唤醒模拟器。 • 活动生命周期中的函数调用顺序如下:onSaveInstanceState() → onPause() → onResume()。Activity进入休眠状态前,系统首先调用onSaveInstanceState ()保存Activity的状态,然后调用onPause()停止与用户交互;在系统被唤醒后,系统调用onResume()恢复与用户的交互。

  22. 2.3 Android程序调试 • LogCat是用来获取系统日志信息的工具,并可以显示在Eclipse集成开发环境中。LogCat能够捕获的信息包括Dalvik虚拟机产生的信息、进程信息、ActivityManager信息、PackagerManager信息、Homeloader 信息、WindowsManager信息、Android运行时信息和应用程序信息等等。在Eclipse的默认开发模式下没有LogCat的显示页,用户可以使用Window → Show View → Other打开Show View的选择菜单,然后在Andoird → LogCat中选择LogCat。这样,LogCat便会在Eclipse的下方区域显示出来。

  23. 2.3 Android程序调试 • LogCat的右上方的5个字母[V]、[D]、[I]、[W]、[E],表示五种不同的日志信息,分别是详细(Verbose)信息、调试(Debug)信息、通告(Info)信息、警告(Warn)信息、错误(Error)信息。不同类型日志信息的级别是不相同的,级别最高的是错误信息,其次是警告信息,然后是通知信息和调试信息,最后是详细信息。 在LogCat中,用户可以通过五个字母图标选择显示的信息类型,级别高于所选类型的信息也会在LogCat中显示,但级别低于所选类型的信息则不会被显示。 • 即使用户指定了所显日志信息的级别,仍然会产生很多日志信息,很容易让用户不知所措。LogCat还提供了“过滤”功能,在右上角的“+”号和“-”号,分别是添加和删除过滤器。用户可以根据日志信息的标签(Tag)、产生日志的进程编号(Pid)或信息等级(Level),对显示的日志内容进行过滤。

  24. 2.3 Android程序调试 • 在Android程序调试过程中,首先需要引入android.util.Log包,然后使用Log.v()、 Log.d()、 Log.i() 、Log.w() 和 Log.e()五个函数在程序中设置“日志点”。每当程序运行到“日志点”时,应用程序的日志信息便被发送到LogCat中,使用者可以根据“日志点”信息是否与预期的内容一致,判断程序是否存在错误。之所以使用5个不同的函数产生日志,主要是为了区分日志信息的类型,其中,Log.v()用来记录详细信息,Log.d()用来记录调试信息,Log.i()用来记录通告信息, Log.w()用来记录警告信息,Log.e()用来记录通错误信息。

  25. 2.3 Android程序调试 • 如果能够使用LogCat的过滤器,则可以使显示的结果更加清晰。下面使用在LogCat右上角的“+”号,添加一个名为LogcatFilter的过滤器,并设置过滤条件为“标签=LOGCAT”。 • 过滤器设置好后,LogcatFilter过滤后的日志信息如图2-11所示。在这之后,无论什么类型的日志信息,属于哪一个进程,只要标签为LOGCAT,都将显示在LogcatFilter区域内。

  26. 谢谢!

More Related