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