《Android安全技术揭秘与防范》——第2.1节Android应用程序概览

简介:

本节书摘来自异步社区《Android开发秘籍(第2版)》一书中的第2章,第2.1节Android应用程序概览,作者 【美】Ronan Schwarz , Phil Dutson , James Steele , Nelson To,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.1 Android应用程序概览
Android开发秘籍(第2版)
Android应用程序包含的功能五花八门,比如编辑文本、播放音乐、启动闹钟或是打开通讯录等。这些功能可以被分类对应到4类Android组件之中,如表2-1所示,每一类都对应一个Java基本类。


ff2cb56b1d27bc9763aff68805dd008b1399ccf9

每个应用程序都由一个或多个这样的组件组成。当要用到某个组件时,Android操作系统就会将其初始化。其他应用程序在指定的权限内也可以使用它们。

随着在操作系统中展现多种功能(有些功能甚至与预期的应用程序无关,如呼入电话),每个组件经历了生命周期的创建(create)、聚焦(focus)、失去焦点(defocus)和销毁(destroy)过程。对于优雅的操作(比如保存变量或者恢复用户界面元素)可以重写其默认行为,使交互对用户更加友好。

除了ContenProvider组件,每个组件都需要一个叫做Intent的异步消息来激活。Intent可包含一组(Bundle)描述该组件的辅助数据。这也提供了一种在组件之间传递消息的方法。

本章最后将使用最常见的组件Activity演示前面提到的概念。由于Activity总是和具体的用户交互相关,所以每个Activity在创建时会自动创建一个新窗口。当然还会提到一些关于UI的概要介绍。至于Service和BroadcastReceiver这两个组件我们将会在第3章中讲解,而ContentProvider则会在第11章中阐述。

技巧1:创建项目和Activity
创建Android项目或其组件最直截了当的方式,当属使用Eclipse集成开发环境(IDE)。这样做可以确保所有辅助文件被正确安装。用Eclipse新建Android项目的步骤具体如下。

(1)在Eclipse下,选择File → New → Android Application Project,这样会出现新建Android项目的界面。

(2)填写项目名称,比如SimpleActivityExample。

(3)填写应用程序的名称,比如Example of Basic Activity。

(4)填写包名称,例如com.cookbook.simpleactivity。

(5)选择SDK的最低要求,这将成为可以运行应用的最低Android版本。建议最低选择API Level 8或Android 2.2。

(6)从给出的选项中选择构建程序的目标SDK版本,此处应选择测试应用时会用到的最高Android版本。

(7)选择用于编译应用的SDK版本,这里应选择可用的最新版本,或者要用到的库所需的最低版本。

(8)选择应用程序的基本主题(theme)。以后还可以按需修改主题,不过在此早些指定一个没有坏处。

(9)接下来,设置另一些项目默认参数。选中Create custom launcher icon一项,以替换当前的默认图标。要在后面的步骤中创建主Activity,请确保你勾选了Create Activity项。

(10)在Configure Launcher Icon界面,可以在文本、一小组剪贴画或磁盘中的图片里面选定应用的图标。系统会基于选定的图像,分别创建符合4种标准分辨率的图标。

(11)要在同一步骤中创建主Activity,应确保勾选了Create Activity项,并选择BlankActivity选项。Fragment的使用将在后面的技巧中予以介绍。

(12)填写Activity和布局的名字,或者维持默认值。要使用默认导航模式中的某一个,需要SDK版本为14或更高才行,因为这有赖于ActionBar的支持。

(13)点击Finish按钮完成这一实例工程的创建。

所有的Activity均继承了抽象类Activity或它的一个子类。每个Activity的入口为onCreate()方法。通常为初始化Activity,都会对该方法进行重写,以完成设置UI、创建按钮监听器(listener)、初始化参数,或是启动线程一类的工作。

如果主Activity并未随项目一起创建,或者需要另行创建一个Activity,那么可以采取以下步骤。

(1)创建一个继承Activity类的新类。在Eclipse下可以这样做:在项目上右击,选择New → Class,然后指定android.app.Activity作为父类。

(2)重写onCreate()函数。在Eclipse下可这样做:在类文件上右击,选择Source → Override/ImplementMethods...,然后选中onCreate()方法。同大多数重写函数一样,重写onCreate()方法需要调用父类的该方法,如若不然,可能在运行时抛出异常。在此,应当首先调用super.onCreate()方法,以确保Activity的正确初始化,如代码清单2-1所示。

代码清单2-1 src/com/cookbook/simple_activity/SimpleActivity.java

package com.cookbook.simple_activity;

import android.app.Activity;
import android.os.Bundle;

public class SimpleActivity extends Activity {

   @Override
   public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
   }
}

(3)如果要用到UI,需在res/layout/目录下的一个XML文件中指定布局。此处该文件称为main.xml,如代码清单2-2所示。

代码清单2-2 res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   >
<TextView
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:text="@string/hello"
   />
</LinearLayout>

(4)使用setContentView()函数设置Activity的布局,并将XML布局文件对应的资源ID作为参数传递给它。此处该参数为R.layout.main,已显示在代码清单2-1中。

(5)在AndroidManifest.xml文件中声明Activity的属性,详细内容会在稍后的代码清单2-5中涵盖。

注意,字符串类型资源均在res/values文件夹下的strings.xml中定义,如代码清单2-3所示。该文件为需要被修改或重用的字符串提供了一个集结地。

代码清单2-3 res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="hello">Hello World, SimpleActivity!</string>
   <string name="app_name">SimpleActivity</string>
</resources>

下面要对项目的结构及其他一些自动生成的内容进行详细探究。

2.1.1 项目目录结构及自动生成的内容
项目结构是用户生成的文件与自动生成文件的混合体。图2-1给出了Eclipse Package Explorer(Eclipse包浏览器)中显示的项目结构的一个示例。


1bd070b242f78cb2715553607db6be0bcb0c70d5

用户生成的文件包括以下这些。

src/目录包含了用户为应用编写或导入的Java包。每个包可以包含多个.java文件,分别代表不同的类。
res/layout/下包含了为每一屏界面指定布局的XML文件。
res/values/下含有被其他文件所引用的XML文件。
res/values-v11/用于存放Honeycomb1及更高版本设备使用的XML文件。
res/values-v14/用于存放Ice Cream Sandwich2及以上版本设备使用的XML文件。
res/drawable-xhdpi/、res/drawable-hdpi/、res/drawable-mdpi/和res/drawable-ldpi/分别包含应用在极高、高、中、低每英寸点数分辨率下所用的图片。
assets/下存有应用要用到的非媒体文件。
AndroidManifest.xml用于向Android系统指定该项目的特性。
每个名为res/values-XX的文件夹下均生成有styles.xml。这是因为Android基本主题从Honeycomb版本起变为了Holo,这导致应用的主题拥有不同的父主题。

自动生成的文件则有以下这些。

gen/之下包含了自动产生的代码,包括生成的类文件R.java。
project.properties里含有项目设定。尽管是自动生成的,它也应当被纳入版本控制之下。
应用程序的资源包括描述布局的XML文件、定义包括如字符串和UI元素标签等的各种值的XML文件,以及其他支持文件,比如图片和声音。编译时,对资源的引用都会收集到一个名为R.java的自动生成的包装类(wrapper class)中。Android Asset打包工具会自动生成该文件。代码清单2-4给出了技巧1的项目产生的R.java的内容。

代码清单2-4 gen/com/cookbook/simple_activity/R.java

/* AUTO-GENERATED FILE. DO NOT MODIFY.
 *
 * This class was automatically generated by the
 * aapt tool from the resource data it found. It
 * should not be modified by hand.
 */

package com.cookbook.simple_activity;

public final class R {
   public static final class attr {
   }
   public static final class drawable {
     public static final int icon=0x7f020000;
   }
   public static final class layout {
     public static final int main=0x7f030000;
   }
   public static final class string {
     public static final int app _ name=0x7f040001;
     public static final int hello=0x7f040000;
   }
}

在这里,每个资源都被映射到一个独一无二的整型(integer)值。通过这种方式,R.java类提供了一种在Java代码中引用外部资源的办法。例如,要在Java中引用main.xml,就使用整型值R.layout.main。而要在XML文件里引用该资源,则应使用“@layout/main”字符串。

表2-2展示了在Java或XML文件中引用资源的方法。注意,要定义一个ID名为home_button的新按钮,需要在其标识字符串前面加上一个加号,就像这样:“@+id/home_button”。关于资源更完整的细节请见第5章,此处介绍的内容对于学习本章的技巧已经足够。


9814694ac35ef00aafd4c4a9bfbe879a210f4abd

2.1.2 Android包和manifest文件
Android项目,有时也被称为Android包,乃是Java包的集合。不同的Android包可以拥有相同的Java包名,但Android设备上安装的每个Android包的名字都应当是独一无二的。

为让操作系统访问这些包,每个应用程序必须在一个名为AndroidManifest.xml文件中声明它所有可用的组件。此外,该文件还包含运行应用所需的权限和行为。代码清单2-5给出了技巧1对应的AndroidManifest.xml的内容。

代码清单2-5 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.cookbook.simple_activity"
        android:versionCode="1"
        android:versionName="1.0">
   <application android:icon="@drawable/icon"
           android:label="@string/app_name">
     <activity android:name=".SimpleActivity"
           android:label="@string/app_name">
       <intent-filter>
          <action android:name="android.intent.action.MAIN" />
          <category android:name="android.intent.category.LAUNCHER" />
       </intent-filter>
     </activity>
   </application>
   <uses-sdk android:minSdkVersion="8" />
</manifest>

第一行对于Android中的所有XML文件都是标准的和必须的,用于指定编码。manifest元素定义了Android包的名字和版本。versionCode是一个整型值,可在程序中对其求值,以确定版本的高低关系。versionName以人们可读懂的格式表示了声明的主版本号和子版本号。

application元素定义了用户会在Android设备菜单中看到的应用程序的图标和标签。标签是一个字符串,应当足够简短,以便在用户设备中正确显示在图标下方。通常,该名字最长为两个单词,每个单词由10个连续的英文字符构成。

activity元素定义了应用启动时调用的主Activity,以及Activity活动时标题栏(title bar)中显示的名称。在此需要给Java包指定名字,本例中为com.cookbook.simple_activity. SimpleActivity。由于Java包名通常与Android包名相同,常常使用简化形式.Simple- Activity。然而,最好记得Android包和Java包还是有区别的。

intent-filter元素向Android系统说明组件的功能,为此,它可以包含多个action、category或data元素。该元素在本书的许多技巧中都会用到。

uses-sdk元素定义了运行应用所需的API级别。一般来说,API级别会像下面那样指定:

<uses-sdk android:minSdkVersion="integer"
      android:targetSdkVersion="integer"
      android:maxSdkVersion="integer" />

由于Android系统按向前兼容原则构建,强烈不推荐使用maxSdkVersion参数(在Android 2.0.1及以后版本中它已经被剔除掉了)。然而Google Play仍然在使用它作为一个过滤参数,在运行大于这一参数的SDK版本的设备上,该应用程序就会被显示为不可下载。

targetSdkVersion并非必须指定,但指定它可以让拥有相同SDK版本的设备关闭兼容性设置,这可能会提升操作速度。应该始终指定minSdkVersion的值,以确保一个应用运行在不支持其所需特性的平台上时不会崩溃。在指定该值时应总是选择可能的最低API级别。

AndroidManifest.xml文件还可以包含运行该应用所需的权限设定。后面的章节会给出关于所提供选项的更完整介绍,以上所讲对于本章的技巧来说已经够用了。

技巧2:重命名应用程序的某些部分
有时候Android项目的某部分需要被重命名。也许有某个文件被(比如从本书中)手动复制进了项目。也许应用程序在开发期间改了名,也需要在文件系统树上反映出来。这项工作由自动化工具协助我们完成,同时确保那些交叉引用也被自动更新。例如,在Eclipse IDE里,有多种办法实现对应用程序某一部分的重命名。

要重命名Android项目,步骤如下。
(1)在项目上右击,选择Refactor → Move将其移动到文件系统中的一个新目录中。
(2)在项目上右击,选择Refactor → Rename重命名项目。
要重命名Android包,步骤如下。
(1)在包上右击,选择Refactor → Rename重命名包。
(2)编辑AndroidManifest.xml文件,确保新的包名在其中得到反映。
要重命名Android类(比如像Activity、Service、BroadCastReceiver和ContentProvider这样的主要组件),步骤如下。
(1)在.java文件上右击,选择Refactor → Rename重命名类。

(2)编辑AndroidManifest.xml文件,确保android:name之下的名字得到更新。

注意,重命名其他文件,诸如XML文件,通常需要手动更改Java代码中相应的引用。

技巧3:使用库项目
库项目(library project)允许资源和代码在其他应用程序中被复用,它们也被用作UI库以使较老的设备能支持新的特性。库项目在SDK工具版本14中被首次引入。库项目与一般的Android项目很类似,同样包含源码、资源文件夹和manifest文件。二者主要的区别在于库项目不能独立运行,且无法被编译成.apk文件。创建库项目的步骤如下。

(1)在Eclipse下,选择File → New → Android Application Project,这样会出现新Android项目的创建界面。

(2)填写项目名称,比如SimpleLibraryExample。

(3)填写应用程序的名称,比如Example of Basic Activity。

(4)填写包名称,例如com.cookbook.simplelibrary。

(5)从给出的选项中选择构建程序的目标SDK版本,这些选项基于开发机上已安装的SDK版本而提供。

(6)取消勾选Create custom launcher icon一项,因为库不需要图标。

(7)勾选Mark this project as a Library一项。

(8)要在库中包含Activity,应选中Create Activity项。此处创建的Activity会在主项目中用到,目前勾选上Create Activity并选择BlankActivity即可。

(9)填写活动名称,或者维持默认。

(10)把布局名改为lib activity main。由于所有资源最终都会被编译进单个R类文件中,最好给库的所有资源起一个统一的前缀,以避免命名冲突。

(11)点击Finish按钮完成库项目的创建。

要使用该库,需要一个主项目。依照技巧1的方法为工作区添加一个新项目,只需要进行一点微小的改动,即不需为该项目创建Activity,取而代之地,使用之前创建的库项目中的Activity。

要在主项目中引用库项目,操作如下。

(1)在Eclipse里右击项目并选择Properties → Android。

(2)向下滚动到库部分,并点击Add。

(3)会弹出一个对话框,显示工作区内所有可用的库项目,从中选择SimpleLibrary并按下OK按钮。

现在项目名称和引用路径已显示在Properties页中,会有一个绿箭头表明引用通过了检查。如果找不到引用路径,则会显示一个红叉。

添加了库项目后,建议对工作区做一次干净而完全的构建操作,以确保我们所做的变更能按预期工作。

在内部,库引用被保存在project.properties文件中,该文件同时为Eclipse和Ant所用。该文件内容应该像下面这样:

target=android-16
android.library.reference.1=../SimpleLibrary
代码清单2-6将库中的Activity添加到AndroidManifest.xml文件里,并将其设为默认启动的Activity。

代码清单2-6 主项目的AndroidManifest.xml

<manifest xmlns:android="[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"
  package="com.example.simpleproject"
  android:versionCode="1"
  android:versionName="1.0">
  <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />
  <application android:label="@string/app_name"
    android:icon="@drawable/ic_launcher"
    android:theme="@style/AppTheme">
    <activity
      android:name="com.cookbook.simplelibrary.LibMainActivity"
      android:label="@string/title_activity_activity_main" >
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>
</manifest>

在此注意,应用程序的包名与Activity的名字截然不同,由于Activity是从库项目中调用的,为其设定的名称必须是完全合格的包名和类名。

现在项目可以在Eclipse中运行了,库中的Activity会在前台显示。

库项目有很多用途,从为主项目设置不同主题、但运行在相同基础代码之上的white-label3应用,到使用像ActionBarSherlock这样的UI库为老Android设备带来新的外观和感觉。

1Honeycomb为Android 3.0~3.2版的别名,这里特指对应API Level 11的3.0版本。——译者注
2Ice Cream Sandwich为Android 4.0版的别名,对应API Level 14。——译者注
3所谓white-label是这样一类产品和服务,它们由一家公司(制造商)生产,但其他公司(市场商)可以对其进行重塑,让它们以自己的面貌面世。——译者注

相关文章
|
8天前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin协程的实践之路
【4月更文挑战第30天】在移动开发领域,随着用户需求的不断增长和设备性能的持续提升,实现流畅且高效的用户体验已成为开发者的首要任务。针对Android平台,Kotlin协程作为一种新兴的异步编程解决方案,以其轻量级线程管理和简洁的代码逻辑受到广泛关注。本文将深入探讨Kotlin协程的概念、优势以及在实际Android应用中的运用,通过实例演示如何利用协程提升应用性能和响应能力,为开发者提供一条构建更高效Android应用的实践路径。
|
1天前
|
安全 Java Android开发
构建高效Android应用:采用Kotlin进行内存优化的策略
【5月更文挑战第8天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,合理管理内存资源是确保应用流畅运行的关键因素之一。近年来,Kotlin作为官方推荐的开发语言,以其简洁、安全和互操作性的特点受到开发者青睐。本文将深入探讨利用Kotlin语言特性,通过具体策略对Android应用的内存使用进行优化,旨在帮助开发者提高应用性能,减少内存消耗,避免常见的内存泄漏问题。
3 0
|
2天前
|
移动开发 数据库 Android开发
构建高效Android应用:Kotlin协程的全面应用
【5月更文挑战第7天】 在移动开发领域,性能优化与流畅的用户体验是至关重要的。随着Kotlin语言的流行,其并发神器——协程,已成为提升Android应用性能的重要工具。本文将深入探讨如何在Android项目中利用Kotlin协程进行异步编程、网络请求和数据库操作,以及如何通过协程简化代码结构,增强应用的响应性和稳定性。我们的目标是为开发者提供一套实用的协程使用模式和最佳实践,以便构建更加高效的Android应用。
15 3
|
2天前
|
移动开发 数据库 Android开发
构建高效Android应用:Kotlin与协程的完美结合
【5月更文挑战第7天】 在移动开发领域,性能优化和资源管理始终是核心议题。随着Kotlin语言的普及,其提供的协程特性为Android开发者带来了异步编程的新范式。本文将深入探讨如何通过Kotlin协程来优化Android应用的性能,实现流畅的用户体验,并减少资源消耗。我们将分析协程的核心概念,并通过实际案例演示其在Android开发中的应用场景和优势。
|
5天前
|
移动开发 前端开发 Android开发
构建高效Android应用:探究Kotlin协程的优势
【5月更文挑战第4天】 在移动开发领域,尤其是对于Android开发者而言,编写响应迅速且高效的应用程序至关重要。Kotlin作为一种现代的编程语言,其提供的协程特性为异步编程带来了革命性的改变。本文将深入探讨Kotlin协程在Android开发中的应用优势,并通过实例代码展示如何利用协程简化异步任务处理,提高应用性能和用户体验。
|
5天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能对比
【5月更文挑战第4天】在移动开发的世界中,性能一直是衡量应用质量的重要指标。随着Kotlin的兴起,许多Android开发者开始考虑是否应该从传统的Java迁移到Kotlin。本文通过深入分析两者在Android平台上的性能差异,帮助开发者理解Kotlin在实际项目中的表现,并提供选择编程语言时的参考依据。
20 5
|
6天前
|
缓存 测试技术 Android开发
构建高效的Android应用:从设计到实现
【5月更文挑战第2天】 在移动设备日益普及的今天,打造一个既快速又流畅的Android应用对于开发者而言至关重要。本文将深入探讨如何优化Android应用的性能,涵盖UI设计的最佳实践、代码层面的性能提升技巧以及利用最新的Android框架和工具进行应用开发的策略。我们将通过实例分析,揭示那些影响应用响应速度和稳定性的关键因素,并提出切实可行的解决方案,帮助开发者构建出色的用户体验。
|
7天前
|
缓存 移动开发 Android开发
构建高效Android应用:从系统优化到用户体验
【5月更文挑战第2天】 在移动开发的浪潮中,创造一个流畅且响应迅速的Android应用是每个开发者追求的目标。本文将深入探讨如何通过系统级别的优化和细致的设计考量,提升应用性能并增强用户满意度。我们将从减少应用启动时间、内存管理的最佳实践、电池寿命的优化策略以及用户界面(UI)设计的心理学影响等方面,展开全面而具体的技术讨论。
|
8天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【5月更文挑战第1天】 在移动开发的世界中,性能优化始终是开发者关注的焦点。随着Kotlin的兴起,许多团队和开发者面临着一个选择:是坚持传统的Java语言,还是转向现代化、更加简洁的Kotlin?本文通过深入分析和对比Kotlin与Java在Android应用开发中的性能表现,揭示两者在编译效率、运行速度和内存消耗等方面的差异。我们将探讨如何根据项目需求和团队熟悉度,选择最适合的语言,以确保应用的高性能和流畅体验。
|
8天前
|
缓存 安全 Android开发
构建高效Android应用:采用Kotlin进行内存优化
【5月更文挑战第1天】随着移动设备的普及,用户对应用程序的性能要求越来越高。特别是对于Android开发者来说,理解并优化应用的内存使用是提升性能的关键。本文将探讨使用Kotlin语言在Android开发中实现内存优化的策略和技术。我们将深入分析Kotlin特有的语言特性和工具,以及它们如何帮助开发者减少内存消耗,避免常见的内存泄漏问题,并提高整体应用性能。