The Ingredients of an Android Application
Based on the foundation laid in the last chapter for writing robust Java code, this chapter introduces the major high-level concepts involved in programming for the Android platform.
Traditional Programming Models Compared to Android
When starting applications, operating systems traditionally use a single entry point, often called main, which might parse some command-line arguments and then proceed to execute a loop that would read user input and produce output. The OS would load the program code into a process and then start executing it. Conceptually, this kind of process would look something like Figure 3-1.
Figure 3-1. A simple application in a process
With programs written in Java, it gets a little more complex: a Java virtual machine (VM) in a process loads bytecode to instantiate Java classes as the program uses them. This process looks something like Figure 3-2. If you use a rich graphical user interface system like Swing, you might start a UI system and then write callbacks to your code that process events.
Figure 3-2. A Java application, running in a Java virtual machine, in a process
Android introduces a richer and more complex approach by supporting multiple application entry points. Android programs should expect the system to start them in different places, depending on where the user is coming from and what she wants to do next. Instead of a hierarchy of places, your program is a cooperating group of components that may be started from outside the normal flow of your application. For example, a component to scan a bar code provides a discrete function that many applications can integrate into their UI flow. Instead of relying on the user to directly start each application, the components themselves invoke one another to perform interactions on behalf of the user
Activities, Intents, and Tasks
An Android activity is both a unit of user interaction—typically filling the whole screen of an Android mobile device—and a unit of execution. When you make an interactive Android program, you start by subclassing the Activity class. Activities provide the reusable, interchangeable parts of the flow of UI components across An-droid applications.
How, then does one activity invoke another, and pass information about what the user wants to do? The unit of communication is the Intent class. An Intent represents an abstract description of a function that one activity requires another activity to perform, such as taking a picture. Intents form the basis of a system of loose coupling that allows activities to launch one another. When an application dispatches an intent, itrsquo;s possible that several different activities might be registered to provide the desired operation.
You have already 'written' the code for an activity in the test application you created to verify that your Android SDK is correctly installed. Letrsquo;s take a look at that code again:
public class TestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); setContentView(R.layout.main);
}
}
When the system starts this activity it calls the constructor for TestActivity, a subclass of Activity, and then calls its onCreate method. This causes the view hierarchy descri-bed in the main.xml file to load and display. The onCreate method kicks off the life cycle of the Activity, which Chapter 11 covers in detail.
The Activity class is one of the most important classes in the Android system, promoting apps modularity and allowing functionality to be shared. An Activity interacts with the Android runtime to implement key aspects of the application life cycle. Each activity can also be independently configured, through a Context class.
Each activity in an Android application is largely separate from other activities. The code that implements one activity does not directly call methods in the code that implements another activity. Other elements in the Android framework—such the Intent already mentioned—are used to manage communication instead. Thus, you are discouraged from keeping references to Activity objects. The Android Runtime Environment, which creates and manages activities and other application components, of-ten reclaims the memory they use in order to restrict individual tasks to relatively small amounts of memory. You will find ad hoc attempts to manage activity memory to be largely counterproductive
Instead of a user interface flow control based on method calls, applications describe an Intent that they want to execute and ask the system to find one that matches. The Android Home screen application starts your program using these descriptions, and each app can then do the same using its own choice of intents. Android Developers call the resultant flow a “task”: a chain of activities that often span more than one application, and, indeed, more than one process. Figure 3-3 shows a task spanning three applications and multiple activities (Table 3-1 gives an example). The chain of activities comprising this task spans three separate processes and heaps, and can exist independently of other tasks that may have started other instances of the same Activity subclasses.
Table 3-1. Examples of a single task, made up of activities across applications
剩余内容已隐藏,支付完成后下载完整资料
Android应用程序的组成
基于上一章为编写健壮的Java代码所奠定的基础,本章介绍了Android平台编程所涉及的主要高级概念。
与Android相比较的传统编程模型
在启动应用程序时,操作系统通常使用单个入口点(通常称为main),该入口点可能会解析一些命令行参数,然后继续执行循环,该循环将读取用户输入并产生输出。操作系统会将程序代码加载到进程中,然后开始执行它。从概念上讲,这种过程类似于图3-1。
图3-1. 过程中的一个简单应用
对于用Java编写的程序,它变得稍微复杂一点:进程中的Java虚拟机(VM)加载字节码,以便在程序使用Java类时实例化它们。这个过程类似于图3-2。如果你使用像Swing这样的丰富的图形用户界面系统,你可能会启动一个UI系统,然后向处理事件的代码编写回调。
图3-2. 在Java虚拟机中运行的Java应用程序
Android 引入了一个更丰富和更复杂的方法来支持多个应用程序的入口点。Android程序应该等待系统在不同的地方启动它们,这取决于用户来自哪里以及她下一步要做什么。你的程序不是一个等级制度,而是一组协作的组件,这些组件可能从应用程序的常规流之外启动。例如,扫描条形码的组件提供了一个离散功能,许多应用程序都可以将其集成到它们的UI流中。组件本身调用以代表用户执行交互,而不是依赖于用户直接启动每个应用程序
活动,意图和任务
一个Android活动既是一个用户交互的单元--通常充满Android移动设备的整个屏幕--也是一个执行单元。当您创建一个交互式Android程序时,您首先要对Activity类进行子类化。活动提供了
跨Android应用程序的UI组件流中可重用,可互换的部分。
那么,一个活动如何调用另一个活动,并传递有关用户想要做什么的信息呢? 通信的单位是Intent类。Intent代表一个活动要求另一个活动执行的功能的抽象描述,例如拍照。 Intent构成了一个松散耦合系统的基础,该系统允许活动相互启动。当一个应用程序发送一个意图时,可能会将几个不同的活动注册到提供所需的操作中。
您已经在您创建的测试应用程序中的一个活动“编写”了代码,以验证您的Android SDK是否正确安装。我们再来看看那段代码:
public class TestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); setContentView(R.layout.main);
}
}
当系统启动这个活动时,它调用Activity的子类TestActivity的构造函数,然后调用它的onCreate方法。这将导致 main.xml 文件中描述的视图层次结构加载和显示。onCreate方法启动了活动的生命周期,第11章对此进行了详细介绍。
Activity类是Android系统中最重要的类之一,它促进了应用程序的模块化,并允许功能共享。一个活动与Android运行时交互,以实现应用程序生命周期的关键方面。每个活动也可以通过上下文类独立配置。
Android应用程序中的每个活动在很大程度上都与其他活动分开。 实现一个活动的代码不直接调用实现另一个活动的代码中的方法。Android框架中的其他元素--比如前面提到的Intent--被用来管理通信。因此,不鼓励您保留对活动对象的引用。创建和管理活动和其他应用程序组件的 android 执行期函式库通常会回收它们使用的内存,以便将单个任务限制在相对较小的内存量。您会发现管理活动内存的临时尝试在很大程度上适得其反。
应用程序不是基于方法调用的用户界面流控制,而是描述它们想要执行的Intent,并要求系统找到匹配的意图。Android主屏幕应用程序使用这些描述启动程序,然后每个应用程序都可以使用自己选择的Intent来执行相同的操作。Android开发人员将结果流称为“任务”:一系列活动通常跨越一个以上的应用程序,甚至跨越一个以上的流程。图3-3显示了一个跨越三个应用程序和多个活动的任务(表3-1给出了一个示例)。组成此任务的活动链跨越三个独立的进程和堆,并且可以独立于可能启动了相同活动子类的其他实例的其他任务而存在。
表3-1. 单个任务的示例,由跨应用程序的活动组成
App |
Activity |
Userrsquo;s next action |
||
Messaging |
View list of messages |
User taps on a message in the list |
||
|
App |
Activity |
Userrsquo;s next action |
|
Messaging |
View list of messages |
User taps on a message in the list |
||
Messaging |
View a message |
User taps Menu→View Contact |
||
Contacts |
View a contact |
User taps Call Mobile |
||
Phone |
Call the contacts mobile number |
|||
|
图3-3. 跨越多个应用程序的单个任务中的活动
其他Android组件
Android中的其他三个应用于应用程序的组件:服务、内容提供商和广播接收器。服务类支持后台功能.内容提供器类为多个应用程序提供对数据存储的访问,广播接收器允许多个个部分收听应用程序广播的意图。
您会发现,与其组件相比,应用程序本身是一个相对不重要的单元。精心设计的应用程序“溶解”到Android环境中,在那里他们可以在其他应用程序中启动活动来借用他们的功能,并通过使用支持Android组件来提供或增强他们自己的功能。你可以把Android的内容提供商和意图看作是你应该学会使用的次要API,以便利用Android最强的功能,并与Android平台无缝集成。
服务
Android Service类是用于后台任务,这些任务可能是活动的,但在屏幕上看不到。音乐播放应用程序可能会作为一种服务来实现,以便在用户查看网页时继续播放音乐。服务还允许应用程序通过长期连接共享功能..这种做法让人联想到FTP和HTTP等互联网服务,它们会等到客户端的请求触发它们。Android平台避免了回收服务资源,因此一旦服务启动,除非内存受到极大限制,否则它很可能是可用的。
与Activity一样,Service类提供了控制其生命周期的方法,例如停止和重新启动服务。
内容提供者
内容提供者组件大致类似于RESTfulWeb服务:您使用URI找到它们,以及内容提供者子类并行RESTfulWeb操作的操作,例如放置和获取数据。一个以content://为开始的特殊的URI,它可以在本地设备中被识别,允许您访问内容提供程序数据。要使用内容提供程序,你需要指定URI以及如何对引用的数据进行操作。以下是内容提供程序操作列表,它提供了众所周知的四种基本数据处理活动:创建(插入)、读取(查询)、更新和删除:
插入
内容提供程序类的插入方法类似于REST POST操作。它将新记录插入数据库。
查询
内容提供程序类的查询方法类似于REST GET操作。它返回一个名为Cursor的专门集合类中的一组记录。
更新
内容提供程序类的更新方法类似于REST UPDATE操作。它用更新的记录取代数据库中的记录。
删除
内容提供程序类的删除方法类似于REST DELETE操作。它从数据库中删除匹配记录。
内容提供者组件是Android内容模型的核心:通过提供内容提供者,您的应用程序可以与其他应用程序共享数据,并管理应用程序的数据模型。伴随类Content Resolver使Android系统中的其他组件能够找到内容提供商。您将在整个平台中找到内容提供者,这些提供者既用于操作系统,也用于其他开发人员的应用程序。值得注意的是,核心Android应用程序使用内容提供商,这些内容提供商可以为新的Android应用程序提供快速和复杂的功能,包括浏览器、日历、联系人、呼叫日志、媒体和设置的提供商。
内容提供商在其他平台上发现的IPC系统中是独一无二的,例如CORBA、RMI和DCOM,它们注重于远程过程调用。 内容提供者既是一种持久机制,也是进程间通信的一种形式。内容提供者不仅仅只是启用进程间方法调用,还允许开发人员跨进程有效地共享整个SQL数据库:内容提供者不仅仅是共享对象,而是管理整个SQL表。
使用内容提供程序
由于它在Android中的重要性,我们在这里提供了一个简短的介绍来编写一个使用内容提供程序的客户端。这个例子使用了一个最重要的内容提供者-联系人数据库-应该让你对内容提供者如何适合你的应用程序有一个更有基础的理解。内容提供器类提供中心内容提供器API,您可以对其进行子类型操作特定类型的数据。 活动使用Content Resolver类和相关URL访问特定内容提供程序实例如下:
// code from an activity method
ContentProviderClient client = getContentResolver().
acquireContentProviderClient('content://contacts/people');
ContentProvider provider = client.getLocalContentProvider();
使用内容提供程序涉及使用UriMatcher类定义的REST风格的URI调用其数据操作。URI Matcher为基于REST的URL提供了一个简单的字符串匹配实用程序,并支持通配字符串。内容提供者URL通常采用以下形式:
content://authority/path/id
其中authority是内容提供程序命名空间的Java包(通常是内容提供程序实现的Java命名空间)。 以下是一些内容提供程序的示例:
//References a person
content://contacts/people/25
//this URI designates the phone numbers of the person whose ID is '25' content://contacts/people/25/phones
当开发人员在内容提供程序上调用查询方法时,调用将返回实现android.database.Cursor接口的Cursor对象。 这个接口允许您使用索引一次检索一个结果(就像数据库中的一行),该索引检索每个结果时自动更新的。 熟悉JDBC的开发人员可以将此与java.sql.ResultSet进行比较。 在大多数情况下,Cursor对象表示SQLite表上查询的结果。开发人员可以使用底层SQLite表的索引访问游标字段。下面是一个迭代Android光标并访问其字段的示例:
// code from an activity method
Cursor contactsCursor =
managedQuery(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if (contactsCursor.moveToFirst()) {
int idx = contactsCursor.getColumnIndex(Contacts.People.DISPLAY_NAME);
do { name = contactsCursor.getString(idx); }
while (contactsCursor.moveToNext()
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[409446],资料为PDF文档或Word文档,PDF文档可免费转换为Word
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。