假设您某天早上醒来,心想:“嘿,我今天要构建一个 Android 应用。”首先,这是一个不错的选择!截至 6 月底,每天有 500,000 台 Android 设备被激活,甚至超过了 iPhone。这意味着您的应用拥有庞大的潜在受众。此外,Android 是使用 Java 构建的。这看起来似乎没什么大不了的,但我使用Objective-C在iOS 平台上工作了几年,虽然我现在对它非常熟悉,但与我在 Android 上的体验相比,iOS SDK的学习曲线要陡峭得多。当我第一次开始使用Android SDK时,Android 感觉更容易上手。也就是说,与您过去构建的任何其他 Java 应用程序相比,Android 有一些明显的区别,我将在第一部分介绍其中一些。
所以随着时间的推移,您已经完成了第一个应用,并将其提交到Android Market。祝贺您,因为您的朋友们都正在下载您的应用并对其进行推文。现在是开始第二个应用的时候了。您花费了几天时间,突然意识到您开始重用第一个应用中的代码,这本身并不是一件坏事。代码重用可能很有价值。但是您注意到有很多样板代码经常重复,这会分散您对业务逻辑的注意力。幸运的是,有一些方法可以改进这一点。
在这篇博客文章中,我将概述 Android 和应用程序生命周期,并讨论框架强加的一些限制。我还将回顾一些技术和第三方项目,这些技术和项目可以帮助您清理 Android 代码,并专注于您希望通过应用实现的目标。
Android 概述
让我们简要概述一下 Android 的工作原理。Android 应用程序 (应用) 是使用 Java 构建的,并编译成类文件。然后将类文件编译成 Dalvik 可执行 (DEX) 格式,以便它们可以在 Android 使用的 Dalvik 虚拟机上运行。转换为 DEX 格式后,类文件将被压缩到 Android 包 (APK) 中,以便分发到设备。由于使用了 DEX 格式,因此 Dalvik VM 不是真正的 Java 虚拟机,因为它不运行 Java 字节码。此外,Dalvik VM 基于 Apache Harmony 项目的一个子集作为其核心类库。这意味着您习惯使用的许多 Java SE 类和方法都可用,但肯定不是全部。我发现API 参考(位于Android 开发者网站上)是回顾这些差异的宝贵资源。
默认情况下,每个 Android 应用程序都会由 Android 操作系统分配一个唯一的 Linux 用户 ID。当由系统启动时,应用程序在其自己的 Linux 进程中运行,在其自己的虚拟机 (VM) 中。系统根据需要管理此进程的启动和关闭。您可以猜到,这意味着每个应用程序都与其他正在运行的应用程序隔离运行。安装后,应用可以请求权限以访问硬件功能或与其他应用程序交互。用户可以选择向应用授予这些权限或不安装它。应用需要或请求的权限在每个应用的 Android 清单文件中定义。这是一个 XML 文件,列出了应用的所有组件以及这些组件的任何设置。四种类型的应用程序组件是活动、服务、内容提供程序和广播接收器。出于本文的目的,我将重点关注活动。
活动基本上代表 Android 应用程序的单个屏幕。例如,Twitter 应用可能有一个登录屏幕、一个包含推文列表的屏幕和一个用于创作新推文的屏幕。这些屏幕中的每一个都代表应用程序中的不同活动。作为开发人员,您永远不会自己实例化活动对象。活动是通过发送称为Intent的异步消息来激活的,如下例所示。
startActivity(new Intent(context, HomeActivity.class));
当调用startActivity(Intent intent)时,系统会创建新实例或重用现有实例,以便向用户显示该活动。重要的是,系统控制应用程序和每个活动的启动和停止以及创建和销毁。如果您想与该过程进行交互,则应用程序和活动类提供用于不同生命周期事件的方法,您可以在子类中覆盖这些方法。
依赖注入
Spring Android项目最近发布了其第四个里程碑版本1.0.0.M4。在这个版本中,我们继续改进了对Android的RestTemplate和Spring Social的支持,简化了进行RESTful HTTP请求和访问受OAuth保护的REST API的过程。虽然我们相信这些对于Android开发来说是很有价值的补充,但一些开发者提出了关于Spring Android中依赖注入支持的可能性问题,因为您可能知道,Spring框架已经提供了一个流行的控制反转(IOC)容器,用于在企业Java应用程序中启用依赖注入。在Spring Android规划的早期阶段,依赖注入支持被确定为项目中可能包含的候选功能。那时,还不清楚这种支持将包含什么内容,以及如何实现。因此,我开始研究和调查在Android中执行依赖注入的可用方法以及局限性。
那么,什么是依赖注入?如果您问两个不同的开发者,您可能会得到两个不同的答案。您可能会听到关于IOC、XML文件、注解或其他一些实现细节。实际上,依赖注入只是一种通过向对象提供其工作所需的内容来减少耦合的技术,而不是让对象访问其环境。这听起来很简单,您可能会认为您已经可以使用类构造函数和setter方法实现这一点,这完全正确。但是,回想一下上面概述部分的内容,Android系统驱动应用程序生命周期,因此我们执行此操作的**方式**是有限的。
Android的方式
无需使用任何第三方库,将依赖项传递给Activity就相当容易。如前所述,系统创建应用程序实例。因此,通过扩展application,您可以有效地创建一个单例依赖项实例,然后任何应用程序中的活动都可以访问该实例。
public class MainApplication extends Application {
private MyService service;
@Override
public void onCreate() {
super.onCreate();
service = new MyServiceImpl();
}
public MyService getMyService() {
return this.service;
}
}
Activity类有一个名为getApplication()的方法,它返回拥有该Activity的应用程序对象的引用。我们只需将其转换为MainApplication,就可以访问MyService的getter方法。当然,Activity现在必须“知道”应用程序,这似乎是一个缺点。但请记住,Activity已经知道其应用程序。该方法是内置的。
public class MainActivity extends Activity {
private MyService service;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainApplication app = (MainApplication…