《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是这样一类产品和服务,它们由一家公司(制造商)生产,但其他公司(市场商)可以对其进行重塑,让它们以自己的面貌面世。——译者注

相关文章
|
2月前
|
IDE Java 开发工具
深入探索安卓应用开发:从环境搭建到第一个"Hello, World!"应用
本文将引导读者完成安卓应用开发的初步入门,包括安装必要的开发工具、配置开发环境、创建第一个简单的安卓项目,以及解释其背后的一些基本概念。通过一步步的指导和解释,本文旨在为安卓开发新手提供一个清晰、易懂的起点,帮助读者顺利地迈出安卓开发的第一步。
220 65
|
2月前
|
存储 Java Android开发
探索安卓应用开发:构建你的第一个"Hello World"应用
【9月更文挑战第24天】在本文中,我们将踏上一段激动人心的旅程,深入安卓应用开发的奥秘。通过一个简单而经典的“Hello World”项目,我们将解锁安卓应用开发的基础概念和步骤。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供一次实操体验。从搭建开发环境到运行你的应用,每一步都清晰易懂,确保你能顺利地迈出安卓开发的第一步。让我们开始吧,探索如何将一行简单的代码转变为一个功能齐全的安卓应用!
|
11天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
11天前
|
存储 搜索推荐 Java
打造个性化安卓应用:从设计到实现
【10月更文挑战第30天】在数字化时代,拥有一个个性化的安卓应用不仅能够提升用户体验,还能加强品牌识别度。本文将引导您了解如何从零开始设计和实现一个安卓应用,涵盖用户界面设计、功能开发和性能优化等关键环节。我们将以一个简单的记事本应用为例,展示如何通过Android Studio工具和Java语言实现基本功能,同时确保应用流畅运行。无论您是初学者还是希望提升现有技能的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧。
|
15天前
|
搜索推荐 开发工具 Android开发
打造个性化Android应用:从设计到实现的旅程
【10月更文挑战第26天】在这个数字时代,拥有一个能够脱颖而出的移动应用是成功的关键。本文将引导您了解如何从概念化阶段出发,通过设计、开发直至发布,一步步构建一个既美观又实用的Android应用。我们将探讨用户体验(UX)设计的重要性,介绍Android开发的核心组件,并通过实际案例展示如何克服开发中的挑战。无论您是初学者还是有经验的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧,帮助您在竞争激烈的应用市场中脱颖而出。
|
16天前
|
算法 Java 数据库
Android 应用的主线程在什么情况下会被阻塞?
【10月更文挑战第20天】为了避免主线程阻塞,我们需要合理地设计和优化应用的代码。将耗时操作移到后台线程执行,使用异步任务、线程池等技术来提高应用的并发处理能力。同时,要注意避免出现死循环、不合理的锁使用等问题。通过这些措施,可以确保主线程能够高效地运行,提供流畅的用户体验。
27 2
|
20天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
46 5
|
20天前
|
移动开发 Dart 搜索推荐
打造个性化安卓应用:从零开始的Flutter之旅
【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
|
30天前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
42 4
|
30天前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
47 2