65.9K
CodeProject 正在变化。 阅读更多。
Home

创建一个简单的 Hello World Android 项目。

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (17投票s)

2014年8月3日

CPOL

33分钟阅读

viewsIcon

53412

downloadIcon

2182

通过编写你的第一个应用程序向世界问好,来真正了解Android。

引言

你已经在电脑上设置好了Android开发环境,请参阅设置你的Android开发环境。你已经拥有了开发Android应用所需的一切。你的第一个Android应用应该是什么呢?传统上,每个程序员写的第一个程序都是向世界问好!你也不例外。还在等什么?让我们开始吧(我是说Android Studio)。

稍等一下,请注意,本文建立在先前文章的学习基础上——即设置你的Android开发环境Android入门介绍,当你需要时,会提醒你参考它们。再稍等一下,这是一次严格的单向跟随之旅,建议你不要跳过任何站点。让旅程开始吧……

准备就绪,开始烹饪~

开灯

启动Android Studio!一个漂亮的加载屏幕,背景闪烁着各种尺寸手机和平板电脑的剪影,让你了解加载进度。(图1)

图1:加载屏幕

过了一会儿,你将看到“欢迎使用Android Studio”屏幕。(图2)

图2:Android Studio欢迎您

准备食材

在欢迎屏幕上,点击新建项目...,开始创建新项目的过程。请按照以下步骤进行。我建议你先使用此示例中的参数。当你更熟悉这个过程后,可以尝试不同的参数。

  1. 填写图3所示的表单

    图3:配置新项目
    图4:编辑包名
    • 应用程序名称是出现在Google Play和用户屏幕上的应用名称。

    • 公司域名是你组织或个人网站的域名。出于此目的,让Android Studio为你决定。

    • 包名是你的应用程序的唯一命名空间,使其区别于Android系统上安装的所有其他应用程序。默认情况下,它通常以反转的公司域名开头,后跟一个句点,然后是应用程序名称(去除空格)。要更改包名,请单击包名字段左端的编辑文本(图4)。

    • 项目位置是你磁盘上存储项目的路径。

    准备就绪后,点击下一步

  2. 选择项目的最低SDK版本,如图5所示

    图5:选择设备形态

    为了帮助你更好地决定最低SDK版本,请点击图5中的帮助我选择,你将看到一个显示Android设备在API级别分布的表单(图6)。

    图6:Android设备在API级别分布

    准备就绪后,点击下一步

  3. 从预定义模板列表中选择空白活动(如图7所示)。滚动查看提供的不同模板。这些模板会自动创建一个Activity和相应的XML文件。你可以使用这些模板快速设置一个基本的Android应用程序,然后可以在设备或模拟器上运行它。

    图7:选择模板

    准备就绪后,点击下一步

  4. 你已到达创建新项目的最后一步。只需保留默认参数。但暂时不要点击完成按钮!让我们看一下那里的三个项目

    图8:选择设备形态
    • 活动名称是UI屏幕的编程名称。这将是应用程序启动时启动的初始屏幕。用OO(面向对象)的术语来说,它是Activity类的子类,并且是用Java编写的。

    • 布局名称是定义Activity中所有组件布局的XML文件的名称。

    • 标题是Activity的标题。

    点击完成继续。

将它们放在一起

你应该看到Android Studio的屏幕显示如下(图9)。你的屏幕布局可能与我的略有不同,但没关系。在这里不可能显示详细的图像,请查看你自己的屏幕。

图9:Android Studio屏幕

饿了吗?想知道你的菜肴会怎么样?让我们开始烹饪和品尝吧。

烹饪它……

还记得你在设置你的Android开发环境中设置的Android虚拟设备(AVD)模拟器吗?你将在该AVD上模拟你的应用程序。请按照以下步骤操作

  1. 在Android Studio的菜单栏上,点击应用 > 编辑配置...(如图10所示)。或者,你可以点击运行 > 编辑配置...

    图10:编辑配置

    准备就绪后,点击下一步

  2. 你将看到一个如图11所示的表单。在目标设备部分,选择模拟器 > 你的AVD名称 > 确定

    图11:选择AVD
  3. 要开始烹饪,点击菜单栏上应用程序图标旁的绿色向右三角形(图10)或点击运行 > 运行“应用”。等待片刻,AVD就出来了!(图12)

    注意
    Android模拟器是一个很棒的工具,除了它的预期用途外,它对你的健康也很有益,尽管是无意的,我发誓,听我说。Android模拟器以其缓慢而闻名,不要期望点击后它能立即响应,你必须非常非常有耐心。但等待是值得的,因为它会按承诺完成工作,而且它会迫使你放慢脚步,这对你的心脏有好处。在我之前的文章中,我曾建议一旦模拟器启动;让它运行,同时做你的工作。
    图12:AVD已启动
  4. 不要用手指,用鼠标在AVD上滑动和点击(触摸)。将钥匙锁符号一直向左滑动,直到它移开,以解锁屏幕,进入主屏幕,浏览菜单,直到找到这个名为我的第一个Android应用的绿色机器人图标(图13)——这就是你刚刚创建并部署到AVD的应用程序。或者,你可以使用电脑键盘来操作AVD;请参阅模拟器按键与键盘按键的映射。例如,切换Ctrl + F11将模拟屏幕方向的变化。试试看!

    图13:应用已部署到AVD
  5. 好的,菜做好了。是时候品尝了。点击我的第一个Android应用图标。你的应用程序会发出“Hello World!”的惊呼(图14)。味道怎么样?

    图14:应用程序在AVD上运行

好吧,我必须承认味道很淡。事实上,你刚才品尝的是Android Studio制作的默认应用——更像方便面。你还没有真正进行烹饪(编码)。稍后你将有机会为你的应用调味,所以请耐心等待。现在,让我们回到开头,更详细地回顾整个过程。

了解你的厨房

仔细看看你Android Studio的界面(图9)。勇敢地去点击界面上的许多菜单项,探索Android Studio提供的各种功能。

例如,要访问Android Studio中的各种工具窗口,请选择视图 > 工具窗口,你将看到一个工具窗口列表供选择(图15)。如果你看看界面的边缘,你会注意到它们也作为菜单项出现在那里。点击这些项目将在屏幕上切换它们的外观,作为不同的窗口窗格。

图15:访问工具窗口

你可能会感到不知所措。放松!我向你保证,这是正常的,当你更多地使用Android Studio进行开发时,你会更好地了解这些功能。

提示
随着时间的推移,你的Android Studio界面可能会变得非常混乱。不用担心!你可以通过选择窗口 > 恢复默认布局Shift + F12将其重置为初始状态。

我让你花点时间熟悉一下Android Studio……

开始烹饪

如果你想为你的应用程序增添风味,你必须首先了解Android Studio如何处理和烹饪你的应用程序。

看看你Android Studio屏幕上的项目窗格。项目窗口充当文件浏览器,以树形层次结构显示Android项目中所有文件的组织。双击每个节点下的任何文件都会在文本编辑器窗口中打开其内容。我们将逐一介绍一些更重要的文件。它们都位于应用节点下。你看到了吗?

布局编辑器

项目窗格中展开应用节点,然后一路导航到子节点应用 > src > main > res > layout,直到找到名为activity_my.xml的文件。双击此文件,你将在布局编辑器窗格中看到布局代码,并在预览窗格中看到可视化布局(图16)。

图16:布局

你看到的是你的第一个Android程序(或Android术语中的Activity)的UI布局,即你在图8中定义的MyActivity。它用XML编写,它的作用是定义一个包含TextView(视图)对象的RelativeLayout(布局)对象(图17)。

图17:XML中的布局代码

TextView对象包含文本值“Hello World!”,你在AVD上看到了它,是通过以下这行代码

android:text="@string/hello_world"

你可能会注意到一个差异,为什么是“@string/hello world”而不是“Hello World!”?很快你就会明白为什么。

XML布局的可视化表示显示在预览窗格中(图18)。它确实显示了“Hello World!”。你可以通过点击Android Studio屏幕右侧边缘的名为预览的垂直菜单项来切换此预览窗格。

图18:可视化预览

你在XML布局中做的任何更改都会立即反映在预览窗格中。让我们现在就试试。

字符串资源

导航到应用 > src > main > res > values,直到找到名为strings.xml的文件。双击此文件,你将在编辑器窗口中看到一些XML格式的字符串值(图19)。此文件应包含应用中使用的所有字符串值。

图19:字符串资源

你已经自己找到了答案。

答案
Hello World!”的值被赋给了一个名为hello_world的静态变量。你在图17的activity_my.xml文件中看到的“@string/hello world”实际上是对名为hello_world的变量的引用。这是Android在XML中引用静态字符串类型资源的方式。以这种方式使用资源的好处显而易见——可重用性和可维护性。你可以在activity_my.xml文件中直接将“Hello World!”的值赋给android:text,但这强烈不推荐。

strings.xml文件中,添加一个名为my_message的新变量,并为其赋值“I love Android!”。就像这样(图20)。

图20:字符串资源

通过点击布局编辑器窗格顶部的相应选项卡,返回到activity_my.xml文件,并添加一个新的TextView对象来显示my_message,如下所示(图21)。

图21:编辑activity_my.xml

看向预览窗格,你看到了什么?哦,有些不对劲。两个字符串挤在了一起(图22)。

图22:有些不对劲

activity_my.xml文件中,执行以下操作

  • RelativeLayout更改为LinearLayout

  • 添加一个新属性

    android:orientation="vertical"

activity_my.xml应该如下所示(图23)。

图23:调试后的activity_my.xml

再次看向预览窗格(慢慢来,以免扭伤脖子),这次你看到了什么?太棒了!它已经修复了(图24)。

图24:已修复!

设计编辑器

我必须承认我一直在瞒着你。如果你在activity_my.xml文件的布局编辑器窗格的左下角查看,你会注意到有两个选项卡,分别标记为设计文本,并且文本选项卡当前被突出显示。是的,你一直在输入纯XML文本。点击设计选项卡,你会惊喜地发现——Android Studio为你提供了一个图形工具来辅助你的布局设计(图25)。

图25:设计模式

这个设计界面的使用非常直观。中间的窗格显示你的应用程序在一个虚拟设备上的可视化屏幕。默认情况下,它显示的是Nexus 4。你可以像这样更改为不同的设备(图26)。

图26:更改虚拟设备

左侧窗格是调色板,其中包含布局、小部件和其他许多组件,你可以将它们拖放到虚拟设备上。右侧窗格显示了项目中使用到的所有布局和视图对象的组件树(上半部分)以及突出显示项的相应属性(下半部分)。在图26中,它显示的是突出显示的LinearLayout对象的属性。

让我们通过在设备屏幕上添加和显示图像来尝试一下设计编辑器。

可绘制资源

首先,你需要将一个图像作为可绘制资源添加到你的项目中。我在本文开头附上了一张名为“android_robot.png”的图像文件。将其下载到你的电脑,然后按照以下步骤添加你的图像资源

  1. 在项目窗格中右键单击res节点,选择新建 > 图像资源(如图27所示)。

    图27:新建图像资源
  2. 你将看到用于管理Android项目中资源的资源工作室表单(图28)。填写参数,如图28所示。选择你已下载到电脑上的“android_robot.png”图像文件。

    图28:资源工作室

    Android系统将执行缩放和调整大小,以使图像适用于不同的屏幕分辨率,正如你在预览中看到的,这张图像将如何出现在不同的屏幕分辨率下——MDPI、HDPI、XHDPI和XXHDPI。它们将存储在单独的文件夹中,即drawable-mdpi、drawable-hdpi、drawable-xhdpi和drawable-xxhdpi。Android操作系统将根据设备的屏幕分辨率选择其中一张图像进行显示。要了解更多关于Android如何支持多屏幕的信息,请访问Android开发者

    准备就绪后,点击下一步

  3. 另一个屏幕将显示每个处理后的图像将保存到的文件夹(图29)。点击完成

    图29:资源工作室

    准备就绪后,点击下一步

  4. 出于好奇,展开项目窗格中的所有可绘制文件夹,你会发现它们都包含“android_robot.png”,但点击它们会发现它们的大小不同(图30)。

    图30:可绘制图像

    准备就绪后,点击下一步

添加图像

调色板窗格的小部件部分,拖放一个ImageView并将其放置在虚拟设备屏幕上第一个TextView上方(图31)。

图31:添加ImageView小部件

看向右边。你应该会在组件树部分的LinearLayout节点下找到一个新添加的imageView1。这是你刚刚添加到屏幕的ImageView小部件的默认id。你可以通过拖放来更改视图对象的位置。如果你在屏幕上定位小部件时遇到困难,这会很有用。

点击以突出显示组件树中的imageView1,向下看,你会在属性部分找到该视图对象的各种属性。滚动此部分中的属性列表,你应该会找到一个id属性,你可以在其中更改其值(图32)。

图32:资源工作室

滚动查找src属性(图33)。

图33:资源工作室

点击src属性旁边的浏览器按钮,你将看到一个资源屏幕,用于选择imageView1对象的图像(图34)。选择“android_robot”并点击确定

图34:选择图像资源

你已成功将图像添加到你的应用程序(图35)。

图35:向屏幕添加图像

在AVD上运行你的应用程序,亲自看看(图36)。

图36:向屏幕添加图像

如果你切换回文本模式,你会在activity_my.xml文件中找到新添加的条目,如图37所示。新的ImageView对象已被赋予了一个唯一的资源ID“@+id/imageView1”。每个资源ID都以“@+id/name”的形式出现,其中加号表示这是一个新ID。

图37:调试后的activity_my.xml

你觉得这道菜现在味道怎么样?现在,我有一个秘密要告诉你。仔细阅读……

R.java

Android一直在默默地将所有资源编译到一个名为R.java的Java类中。R代表Resources。每当编译你的应用程序时,Android都会生成/重新生成R类,其中包含你项目中所有资源的资源ID。你应该不动R。你可以通过图38所示的路径找到它。

图38:R.java

对于每种类型的资源,都有一个R子类。例如,R.string代表所有字符串资源。每个资源都被分配一个唯一的整数作为其资源ID,以便你可以使用它来检索资源。你可以在各自的Java类中找到项目中使用的所有资源,它们都被声明为public static final int变量,并且也是public static final。由于它们是R的子类,可以通过调用R.<类名>来访问它们,例如R.string

R.string

R.string类中,它包含了“hello_world”和“my_message”以及res/values/strings.xml文件中的其他字符串变量(图39)。事实上,你不必将字符串资源文件命名为strings.xml,只要文件的结构遵循图39中的格式并放置在“res/value”目录中,Android就会将其视为字符串资源文件,并自动将其内容包含在R.javastring类中。

你可以通过调用R.string.<变量名>在Java代码的任何地方访问字符串资源,例如R.string.hello_world

要从XML访问它,你之前已经做过了,@string/<变量名>,例如@string/hello_world

图39:字符串资源

R.id

R.id包含imageView1变量,它指向activity_my.xml文件中的ImageView对象(图37)。你可以在Java代码中这样访问此对象

ImageView iv = (ImageView)this.findViewById(R.id.imageView1);

R.layout

R.layout包含activity_my变量,它指向位于res/layoutactivity_my.xml。任何想要使用此布局文件的Activity都会在其onCreate方法中这样做

setContentView(R.layout.activity_my);

到目前为止,我们一直在处理静态组件。谁来负责与用户的动态交互呢?这就引出了Activities

Activity

Android中的Activity顾名思义,它是一个负责与用户进行交互活动的程序。它实际上是一个Java类。为了实现其功能,Activity需要一个它依赖于R.layout类的UI,它需要监视和响应事件,为此它与R.id类协同工作,等等。换句话说,Android设备上的每个屏幕都是通过Activity创建的,每个Activity都依赖于R类中的各种资源来完成其工作

你项目中的Activity可以通过图40所示的路径找到。它被称为“MyActivity.java”(如我们在图8中定义的)。根据你在图7中选择的模板,Android Studio已经创建了一个默认的Activity类,其中包含所有样板代码,这可以为你节省大量开发时间。

图40:MyActivity类

每个Activity中最不可或缺的代码是onCreate方法,它执行初始设置,例如

  • 恢复先前保存的状态
    super.onCreate(savedInstanceState);
  • 将Activity的内容设置为一个视图
    setContentView(R.layout.activity_my);

Android系统中的每个Activity都遵循明确定义的生命周期。它基本上有四种状态和一些关键循环。你可以参考图41,我从Android Developers借来这张图,以便快速了解生命周期。我将把任何详细的讨论推迟到以后,以免让你不知所措。

图41:Activity生命周期

来源:Android Developers

你可以根据项目需求添加任意数量的Activities。让我们尝试为你的应用程序添加一个新的Activity。请按照以下步骤操作

  1. 按照图42所示的路径创建新的Activity。这次你将尝试Login模板。
    图42:创建新Activity

    准备就绪后,点击下一步

  2. 你将看到一个如图43所示的表单。使用Activity名称、布局名称、标题和包名字段的默认值。层级父项字段允许你指定当用户按下设备上的后退按钮时,新Activity应该导航到的父Activity。将其留空。最后,取消选中包含Google+登录复选框,因为我们不使用此功能。

    图43:设置新Activity

    点击完成以创建名为LoginActivity的新Activity。

  3. 导航到activity_login.xml的设计视图,查看新创建的Activity——LoginActivity的可视化布局(图44)。它具有典型登录屏幕的标准功能——一个电子邮件字段、一个密码字段和一个登录按钮。我有一个要求,就是我希望我的应用程序能在点击登录按钮后导航到MyActivity

    图44:activity_login.xml
  4. 双击登录按钮,会弹出一个框(图45)。复制弹出框中的id值。这个按钮资源已被分配了一个资源ID“@+id/email_sign_in_button”。你可以在新创建的名为activity_login.xml的布局文件中的Button元素的android:id属性中找到这个id条目。(如果你愿意查看,你应该能在R.javaid类的静态变量列表中找到这个id值,但要准备好迷失在代码的海洋中,而且你在那里时,记住“只看不碰”。)

    图45:activity_login.xml
  5. 切换到代码编辑器中的LoginActivity.java,按Ctrl + F激活搜索框,然后将上一步复制的id值粘贴到搜索框中。哇!编辑器立即找到了它(图46)。

    图46:LoginActivity.java
  6. onClick方法中的代码替换为如下所示

    public void onClick(View view) {
        //attemptLogin();
        Intent intent = new Intent(getApplicationContext(), MyActivity.class);
        startActivity(intent);
    }
  7. 将鼠标悬停在“Intent”一词上,它会抱怨一些错误(图47)。这是因为Intent类包含在android.content.Intent包中,而该包尚未导入。别担心!只需点击它一次,然后按Alt + Enter,这个问题就会立即消失。感谢Android Studio。(你应该庆幸你听从了我的建议;P)

    图47:LoginActivity.java

    Intent对象是Android描述一条消息的方式,说明它“有意”做某事,即导航到MyActivity。然后,这个Intent对象被传递给startActivity方法来执行预期的操作。

好了,LoginActivity已经完成,我们可以在AVD上测试它吗?还不行。在当前设置中,启动时将启动的Activity是MyActivityLoginActivity将永远没有机会运行。在新的需求中,我们希望LoginActivity成为启动Activity,我们如何实现这一点?

让我为你介绍今天最后但同样重要的客人——Android Manifest

Android Manifest

在每个Android应用程序中,你都会在根目录下找到一个名为AndroidManifest.xml的文件。如果应用程序没有这个文件,Android系统将不允许它运行。Manifest文件是一个XML文件,它包含了Android系统在允许运行任何应用程序代码之前必须知道的关于你的应用程序的所有配置信息——从应用程序的名称、图标、版本,到硬件和软件要求,甚至还过滤进入应用程序的Intents。多么忙碌的家伙,对吧?你可以把它比作ASP.NET应用程序的Web.config文件。我会认为它是应用程序的命令和控制中心。你想了解或处理应用程序的任何事情,都可以问AndroidManifest.xmlAndroid DevelopersAndroid Manifest的功能有全面的列表,自己去看看

回到我们的应用程序,请按照以下步骤修改其AndroidManifest.xml

  1. 按照图48所示的路径导航到AndroidManifest.xml。花点时间浏览其内容,你看到一些熟悉的面孔了吗?
    图48:AndroidManifest.xml

    请注意,AndroidManifest.xml文件中声明了两个活动块——MyActivityLoginActivity。它们之间的区别在于,MyActivity被声明了一个intent-filter元素。

    Intent Filter使Activity等组件能够宣传其功能,即它能响应的Intent类型。只有当组件的功能在Intent Filter中声明时,Android系统才会启动该组件来处理Intent。

    在我们的例子中,通过指定android.intent.action.MAINaction属性和android.intent.category.LAUNCHERcategory属性,intent-filterMyActivity声明为应用程序的顶级入口点,并且也会列在应用程序启动器中。

  2. 一旦你理解了intent filter的工作原理,那么解决方案就非常简单了。在AndroidManifest.xml中将intent-filter元素从MyActivity移动到LoginActivity。就这样。

    图49:修改后的AndroidManifest.xml
  3. 在AVD上进行测试。你会看到它在登录屏幕上启动(图50),按下按钮应该会切换到我的第一个Android应用屏幕(图36)。

    图50:activity_login.xml

开始真实操作

你的应用程序已经完成了。你不想在真机上试试你的应用程序吗?为什么不呢,让我们开始真实操作吧。

如果你拥有Android设备(很可能),你可以像在模拟器上一样开发和调试你的Android应用程序。但是,在开始之前,你必须为开发目的设置好你的设备。建议你参考Android开发者提供的这个全面的指南,该指南涵盖了所有计算机平台来设置你的设备进行开发。图51显示了我的手机已启用开发的状况。

图51:已启用开发者选项

当你的设备设置好后,将其连接到你的电脑,然后按照以下步骤操作

  1. 你以前在第一次设置模拟器时做过这件事(图10)。在Android Studio的菜单栏上,点击应用 > 编辑配置...或点击运行 > 编辑配置...。但这次,在目标设备部分选择USB设备(图52)。

    图52:编辑配置

    完成后,点击确定

  2. 在你的设备上享受你的应用程序吧。从图53到55可以一窥应用程序在我的设备上运行的样子。

    图53:应用程序启动器
    图54:登录
    图55:Hello World!

签名仪式

在未来的某个时候,你可能想考虑发布你的Android应用程序,以便用户可以使用。为此,你应该参考Android开发者网站上关于此事的官方指南。然而,在你向公众发布应用程序之前,你需要用一个数字证书对其进行签名,该证书的私钥应由你(开发者)持有。Android系统不会安装或运行任何未签名应用程序。这是Android系统识别应用程序作者并建立应用程序之间信任的一种方式。你可以使用自签名证书来实现此目的。

因此,即使是调试阶段的应用程序在模拟器或物理设备上运行之前也需要签名证书。但我们不记得在AVD或物理设备上运行应用程序时进行过这个操作。怎么回事?那是因为Android Studio已经自动处理了,而没有打扰我们。让我们来看看Android开发者对此的说法

引用
当你以调试模式构建时,Android SDK构建工具使用Keytool实用程序(包含在JDK中)创建一个调试密钥。由于SDK构建工具创建了调试密钥,它们知道调试密钥的别名和密码。每次以调试模式编译应用程序时,构建工具都会使用调试密钥和Jarsigner实用程序(也包含在JDK中)来签署应用程序的.apk文件。由于SDK构建工具知道别名和密码,因此在每次编译时,工具都不需要提示你输入调试密钥的别名和密码……当你运行或调试应用程序时,调试签名过程会自动发生。

然而,当你以发布模式构建应用程序时,你必须使用你的私钥进行签名。让我们逐步完成使用Android Studio签名应用程序的过程

  1. 选择构建 > 生成签名 APK...(图56)。
    图56:生成签名APK
  2. 你将看到一个如图57所示的表单。选择现有...按钮用于使用现有密钥库文件签名应用程序。我们将创建一个新的密钥库文件,因此请点击创建新...

    图57:生成签名APK向导
  3. 出现“新建密钥库”表单(图58)。在“密钥库路径”中,输入或浏览到要保存密钥库文件的位置,并为密钥库文件命名。密钥库文件顾名思义,是安全证书(密钥)的存储库。填写其他字段。

    图58:新建密钥库

    在点击确定之前,你必须安全地记住这些值。

    • 密钥库密码是访问密钥库所必需的。
    • 密钥别名是指定要使用的密钥所必需的。
    • 密钥密码是访问密钥所必需的。

    点击确定,密钥库将被创建。

  4. 你将看到“生成签名APK向导”表单(图59),只需点击下一步
    图59:生成签名APK向导
  5. 选择release构建类型,然后点击完成(图60)。

    图60:生成签名APK向导
  6. 你可以通过展开Android Studio屏幕底部的消息菜单来查看构建过程的进度(图61)。

    图61:生成的签名APK

到目前为止一切顺利,Android Studio已成功生成签名APK。一个名为app-release.apk的签名安装文件现在可以在项目根目录中的app目录下找到(图60)。

传播好消息

你已经开发了你的第一个Android应用程序,并将其签名成了一个APK安装文件。你迫不及待地想把它展示给你的朋友们,不是吗?这很简单,只需将APK附加到你的电子邮件发送给他们即可。安装只需点击他们Android设备上的APK文件附件。等等!有一个陷阱。你的朋友会收到一条消息,说该APK文件是未知来源,因为它不是来自Google Play,并且默认会被阻止。所以,在给他们的消息中,你应该向他们解释这一点(以减轻他们的恐惧),并教他们如何解除阻止安装——在他们的设备上,转到安全 > 取消选中未知来源。你可能想先给自己发送一份电子邮件并尝试一下。

还有许多其他分发应用程序的方式,你可以从Android Developers了解更多。

获取资源

你开发应用程序所需的一切都住在这个区域——app > src > main(图62)。它的居民包括javares家族,以及孤独但强大的AndroidManifest.xml。你在开发项目时已经遇到过其中的一些成员。然而,res家族中还有许多你尚未遇到过的成员。所以,让我们去拜访他们,以便更好地了解他们。

图62:app目录

res代表Resources。res目录是你Android项目所需的所有资源的存储库。资源是你可以想象到的任何可以用于你的Android应用程序的东西,例如文本、图形、声音、颜色、文件、尺寸、菜单、动画等等。Android会将它们根据资源类型分组并命名到单独的资源目录中,例如我应用中的drawablelayoutmenuvaluesvalues-w820dp(图63)。你可以在这里找到更多关于资源类型的信息。

当你的应用程序编译时,Android会生成一个R.java类(图38),其中包含res目录中所有资源的资源ID。对于每种类型的资源,都有一个R子类(例如,R.string代表所有字符串资源,R.drawable代表所有可绘制资源,等等),对于该类型的每种资源,都有一个静态整数(例如,R.drawable.android_robotR.string.my_message,等等)。这个整数就是你可以用来检索资源的资源ID。

图63:res目录
  • drawable包含位图文件和形状等图形资源。可绘制资源被进一步优化成不同尺寸,以适应不同的屏幕分辨率。它们存储在单独的目录中,即drawable-mdpidrawable-hdpidrawable-xhdpidrawable-xxhdpi。Android操作系统将根据设备的屏幕分辨率选择其中一张图像进行显示。要了解更多关于Android如何支持多屏幕的信息,请访问Android Developers。在你的应用程序中,你将拥有两个图形资源——“android_robot.png”和“ic-launcher.png”,存在于所有可绘制目录中。“ic-launcher.png”用作你设备上启动器图标的默认图像。

  • layout包含定义Android中用户界面的视觉结构的XML文件。你可以使用XML在设计时定义布局,或者使用Java代码动态创建它们。这里的布局目录包含了定义我们Android项目在设计时的各种布局的XML文件。到目前为止,我们有两个布局文件——activity_login.xmlactivity_my.xml,每个文件对应我们项目中的一个Activity。让我们再次回顾一下activity_my.xml,这次仔细看看。

    • 首先,ImageView对象。

      <ImageView
          android:layout_width="89dp"
          android:layout_height="wrap_content"
          android:id="@+id/imageView1"
          android:src="@drawable/android_robot"
          android:layout_weight="0.09" />

      它已通过以下方式分配了“android_robot”可绘制资源

      android:src="@drawable/android_robot"
      

      这就是Android中引用资源的XML方式 => @resourceType/<resourceName>

      如果你想在Java中访问此可绘制资源,请遵循此语法 => R.resourceType.<resourceName>

      R.drawable.android_robot
      注意

      在Android中有两种访问资源的方式

      • 在XML中:@resourceType/<resourceName>

      • 在代码中:R.resourceType.<resourceName>

    • 接下来是LinearLayout声明。

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:paddingLeft="@dimen/activity_horizontal_margin"
          android:paddingRight="@dimen/activity_horizontal_margin"
          android:paddingTop="@dimen/activity_vertical_margin"
          android:paddingBottom="@dimen/activity_vertical_margin"
          tools:context=".MyActivity"
          android:orientation="vertical"
          android:weightSum="1">

      请注意这些,如果你看到数字而不是@diman/xxx_xxx_margin,那么双击该行以揭示其真实身份。

          android:paddingLeft="@dimen/activity_horizontal_margin"
          android:paddingRight="@dimen/activity_horizontal_margin"
          android:paddingTop="@dimen/activity_vertical_margin"
          android:paddingBottom="@dimen/activity_vertical_margin"

      直观地说,它们定义了某种尺寸,但你期望看到的是数字而不是诸如@dimen/xxx_xxx_margin之类的文本。答案在于它的一个家庭成员——值资源目录中的dimens.xml

  • dimens.xml定义了你可以在Android项目中使用尺寸资源。请注意,有两个dimens.xml文件——一个在values目录中,一个在values-w820dp目录中。values目录中的dimens.xml文件如下所示

    <resources>
        <!-- Default screen margins, per the Android Design guidelines. -->
        <dimen name="activity_horizontal_margin">16dp</dimen>
        <dimen name="activity_vertical_margin">16dp</dimen>
    </resources>

    values-w820dp目录中的dimens.xml文件如下所示

    <resources>
        <!-- Example customization of dimensions originally defined in res/values/dimens.xml
             (such as screen margins) for screens with more than 820dp of available width. This
             would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
        <dimen name="activity_horizontal_margin">64dp</dimen>
    </resources>

    values目录中的dimens.xml文件里定义了两个尺寸资源——“activity_horizontal_margin”和“activity_vertical_margin”,它们都有相同的16dp值,而values-w820dp目录中的dimens.xml文件只定义了“activity_horizontal_margin”值为64dp。它们看起来熟悉吗?(向下滚动一点。)哦,是的,它们出现在activity_my.xml文件的LinearLayout声明中。再次,这就是Android以XML方式引用资源的方式 => @resourceType/<resourceName>。我将不再赘述。

    你会问,“这两个哪个将被应用程序使用?”:confused: 这将把我们带到Android中资源本地化的主题。每个应用程序都应提供替代资源来支持特定的设备配置。Android将自动检测设备当前的配置并选择适合你应用程序的资源。你已经看到了drawable的一个例子,其中为存储针对不同屏幕分辨率优化的图形分配了替代资源目录。在这个例子中也是如此,其中values目录是默认资源目录,而values-w820dp目录是替代目录。它们都服务于存储相同名称但值不同的字符串尺寸样式资源的相同目的。当设备屏幕宽度大于820dp时,Android将使用values-w820dp目录中的dimens.xml。任何未在values-w820dp目录中定义的资源都将引用默认的,即values目录中的dimens.xml。所以,如果你的设备宽度大于820dp,Android会将“activity_horizontal_margin”设置为64dp,将“activity_vertical_margin”设置为16dp。你可以在这里了解更多关于资源本地化的信息。

    但是dp是什么?更多 :confused: 它是密度无关像素的缩写。你也可以使用dip。它们是相同的。它是密度无关的,因为当你定义16dp或16dip的东西时,它将在任何屏幕上呈现相同的大小。对于移动设备的多种屏幕尺寸来说,这是多么完美的解决方案。它是Android应用程序推荐的尺寸单位。当然,没有人能阻止你使用其他度量单位。

    Android还有另一个专门为文本创建的单位。它被称为缩放无关像素,简称sp。(sip?不,没有sip。别侥幸。)。它与dp类似,但有一个区别——它允许用户更改字体大小而不影响其他元素的大小。建议对任何文本使用sp

  • strings_xxx.xml定义了你可以在Android项目中使用字符串资源。它位于values资源目录中。到目前为止,我们的项目中有一个名为“strings.xml”和一个名为“strings_activity_login.xml”的字符串XML文件,每个对应我们项目中的一个Activity。我已经详细介绍过字符串资源类型,所以让我们继续。

  • styles.xml定义了用户界面的样式和主题。它位于values资源目录中。它可以应用于任何视图组件、Activity或整个应用程序。你可以在这里了解更多关于样式和主题的信息。

  • menu包含你可以在Android项目中使用的所有菜单资源,如选项菜单、操作栏、上下文菜单和弹出菜单。我们的项目中只有一个菜单资源文件my.xml,它看起来如下(图64)。

    图64:menu资源

    my.xmlMyActivity上创建了一个名为“Settings”的操作栏。到目前为止,你应该能够解释其中包含的XML语法。

在休息站

这是休息站吗?呼!我以为我赶不上了。这场旅程似乎永无止境。尽管如此,一切顺利。你已经用Android做了一些真正的事情,从开发简单的应用程序、调试、测试,到发布它。继续保持!同时,好好休息一下,我们再会。

参考

© . All rights reserved.