返回索引目录
原文链接:Hello, Android_DeepDive.
译文链接:Xamarin.Android开发入门——Hello,Android深入理解
本部分介绍利用Xamarin开发Android应用程序
Hello, Android Deep Dive
在Hello, Android Quickstart(原文,译文)中,我们创建并运行了我们第一个Xamarin.Android应用程序。现在我们对Android应用如何工作进行进一步学习了解,以便于我们开发更加复杂的程序。
在本指南中我们回顾了我们在Hello,Android中的操作步骤,以此来理解我们所做的处理,与此同时,我们可以对Android应用开发基础有一个初步的理解。
我们将涉及以下及部分主题:
- Visual Studio介绍 —— 介绍Visual Studio和新应用的创建
- 解析Xamarin.Android应用 —— 讲诉Xamarin.Android应用的关键部分
-
App基础及架构基础 —— 介绍
Activities
,Android Manifest
和Android开发的常用处理 - UI界面 —— 使用Android设计器创建用户界面
- Activities以及Activity的生命周期 —— Activity生命周期的介绍,以及如何与界面进行关联。
- 测试,部署,以及收尾处理 —— 关于完善应用的一些建议,包括:测试、部署、产品提供等等。
本指南帮助你提高开发单页面Android应用程序的技能和知识。通过通篇学习,你可以对Xamarin.Android应用的各个部分有一定的了解,以及他们是如何配合工作的。
Visual Studio介绍
Visual Studio是微软推出的一款功能强大的IDE环境。它具有一个完备的视图设计器、含有重构功能的文本编辑器,程序集浏览器、源代码集成工具等等。在本指南中,我们将学习含有Xamarin插件的Visual Studio的一些基本功能。
Visual Studio将代码组织为解决方案和项目。一个解决方案可以包含一个或多个项目。一个项目可以是一个应用程序(如IOS或Android)、一个支持类库,一个测试程序等等。在我们的 Phoneword app(我们在Hello,Android教程中创建的)中,我们通过 Android Application 模板添加了一个Android项目至 Phoneword 解决方案中。我们的解决方案如下图所示:
注:由于官网图片失效,此处我们展示Xamarin Studio中的对应图片
Xamarin.Android应用解析
首先我们从解决方案内容开始。在界面右侧的解决方案管理器中,包含项目的目录结构以及所有与解决方案相关的文件:
我们已经创建一个名为 Phoneword 的解决方案,并在内部加了了一个名为 Phoneword_Droid 的Android项目。下面对项目中的内容项进行介绍:
文件夹 | 用途 |
---|---|
引用——Reference | 包括生成和运行应用程序所需的程序集。展开它,可以看到.NET相关程序集引用,如:System ,System.Core 和System.Xml ,除此之外,还有Xamarin的Mono.Android引用。 |
Components | Components目录存放从Xamarin Components商店获取的现成的功能项。关于更多Xamarin Components的内容,见:原文:Xamarin Components walkthrough |
Assets | 应用程序运行所需的文件,包括:字体文件、本地数据文件和文本文件。这个位置的文件可以通过生成的Assets 类进行访问。关于更多Android的Assets信息见:原文:Using Android Assets
|
Properties | 包含AndroidManifest.xml文件——内容为Xamarin.Android应用所需的所有运行要求,包括:名称、版本号、权限等。关于AndroidManifest.xml的文件内容见:原文:AndroidManifest.xml。 Properties 文件夹同样含有AssemblyInfo.cs文件——.NET程序集元数据文件。在创建应用时,最后完善里面关于我们应用的信息内容。 |
Resources | 包含应用的资源文件,如字符串、图片以及布局。我们可以通过Resource 类在代码中获取操作这些资源。关于更多Android Resources的信息见:原文:Android Resources、译文:Xamarin.Android应用基础——Android资源介绍。此目录还包含了一个关于Resources的简要指南—— AboutResources.txt 文件。 |
Resources文件夹
Resources目录包含了三个子文件夹(drawable, layout, values)以及一个 Resource.Designer.cs 文件。关于这些项的概述见下表:
项名称 | 用途 |
---|---|
drawable | drawable文件夹存放绘制资源,如图片。在默认情况下,drawable目录下有一个icon图标文件——Icon.png 。关于绘制资源信息内容见:drawable resources。 |
layout | layout目录包含 Android设计文件(.axml) —— 用于为每个界面或Activity定义交互界面。项目模板自动创建一个名为 Main.axml 的默认layout文件。 |
values | 此目录存放XML文件——用于存储一些简单的值,如字符串,整数和颜色。项目模板默认创建一个字符串存储文件—— String.xml 。 |
Resource.Designer.cs | 即Resource 类,它是一个存储每一个资源唯一ID的分类。它是由Xamarin.Android工具自动创建,且能够自动重建的文件。此文件不能手动修改,因为Xamarin.Android会覆盖任何的手动修改。 |
App基础及架构基础
Android应用没有一个单一的入口——在应用中没有一行代码来让系统启动它。取而代之的是,在将Android整个应用加载到内存期间,当Android创建其中一个类时,应用启动。
Android的这一独特功能对于复杂应用的设计和与Android操作系统交互会很有用。但是,正因为这个特点,也让创建简单的Android应用变得复杂(如:Phoneword 应用)。鉴于这个原因,我们将分两次来介绍Android的系统架构。在本指南中,我们解析使用第一个界面作为入口的应用——这是最常用的方式。在 Hello,Android Multiscreen 指南中,我们将会深入理解更为复杂的Android体系架构,在那里面,我们会讨论使用不同方式启动应用。
Phoeword 方案 - 通过Activity启动
当我们在模拟器或设备上第一次打开Phoneword应用时,操作系统会创建第一个 Activity 。Activity是单屏幕Android应用中的一个特殊的类,它负责绘制及控制交互界面。一旦Android创建了应用的第一个Activity,系统会加载整个应用:
由于Android应用不是线性执行的,那样我们可以在多个入口启动应用 —— Android有自己独特的方式来跟踪哪些类和文件是属于一个应用程序。在Phoneword示例中,所有的应用的组成部分都是通过 Android Manifest xml文件来注册到系统中的。 Android Manifest 的作用是跟踪应用程序的内容、属性和权限,以及将其公开给Android操作系统。我们可以将Phoneword应用理解为由Android Manifest文件整合的文件集合,包括:一个Activity界面、一个资源计划和帮助文件。正如下图所示:
在后面几节,我们会详细介绍上图中Phoneword应用的各个部分的关系,以此更好的理解它。下面我们首先从UI用户界面开始,其中包括Android设计器和 layout 文件。
用户界面-UI
在我们的应用中,Main.axml
是首页的用户界面布局文件。.axml 后缀的文件表示这是一个Android设计文件(axml代表 Android XML )。从Android的角度来看,Main 的名称可以任意,我们可以将layout文件修改为其他的名字。当我们在IDE环境中打开 Main.axml 文件,它将展示Android布局文件的可视化编辑器 —— Android designer :
在 Phoneword 应用中,我们将 TranslateButton 的ID设置为@+id/TranslateButton
:
当我们设置 TranslateButton 的ID属性时,Android设计器将 TranslateButton 控件映射到 Resource
类中,并为 TranslateButton 分配一个资源 ID 。视图 控件与类的映射让我们可以在后台代码中定位和使用 TranslateButton 和其他控件。关于更多详细的信息会在分离代码和视图时介绍。此处你所需要知道的是,界面控件和后台控制代码是通过ID属性来连接上的。
源代码视图
任何在界面上定义的内容都会翻译为XML,以此提供给Xamarin.Android使用。Android设计器提供源代码视图——用于查看生成的XML格式内容。点击设计界面左下方的Source标签即可切换至XML视图,如下图所示:
在我们的示例中,XML源码中应该包含 Text(large), Plain Text, 和两个 Button 元素。
关于Android设计更深入的内容见Xamarin Android设计器概述指南:原文:Designer Overview
我们已经介绍了用户界面设计以及与其相关的界面代码的工具和概念。下面,让我们看看驱动用户界面的后台代码部分——Activities和Activity的生命周期。
Activities和Activity生命周期
Activity类中含有控制交互界面的代码。Activity负责响应用户交互以及提供动态的用户体验。
在本节中,我们将介绍Activity类,讨论Activity的生命周期,并解析在Phoneword应用中控制用户界面的代码。
Activity类
我们的Phoneword应用只有一个界面(Activity)。此控制界面的类名为MainActivity
,它位于 MainActivity.cs 文件中。在Android中,名称MainActivity
并没有什么特殊意义——尽管通常情况下都把应用中的第一个Activity命名为MainActivity
,即使我们将其命名为其他的名称,Android一样可以使用。
当我们打开 MainActivity.cs 文件后,可以看到MainActivity
是Activity
的一个子类,同时还装饰有ActivityAttribute:
[Activity(Label = "Phoneword", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
...
}
Activity特性使用Android Manifest注册Activity,以此告诉Android系统这个类由哪个清单进行管理的部分。其中Label
属性设置界面顶端显示的文本,Icon
设置文本前的图标,如下图所示:
MainLauncher
属性告诉Android系统在应用启动时显示这个Activity。此属性对于多个Activities(界面)的应用会比较重要,具体见:原文:Hello,Android Multiscreen。
现在我们大概知道了MainActivity
,下面将介绍Activity的生命周期。
Activity生命周期
在Android中,Activity在与用户交互期间经历生命周期中的不同阶段。Activity经历的阶段有:创建、启动、暂停、继续和销毁等等。在界面的生命周期中,系统会某些点调用Activity中包含的方法。下图展示了Activity典型的生命周期情况,以及相应的方法调用情况:
通过重写Activity生命周期中的方法,我们可以控制Activity的加载,怎么回应用户,甚至控制在界面从设备屏幕消失后进行什么操作。例如,我们可以重写上面示意图中使用的方法来进行一些重要的任务:
- OnCreate —— 创建视图,初始化变量,以及处理一些在给用户展示Activity之前的工作。此方法在Activity加载到内存中时执行——故执行一次。
- OnResume —— 每次用户切换到此Activity时都要执行的内容。
- OnPause —— 每次用户离开此Activity时,都要执行的操作。
当我们在Activity的生命周期方法中添加个人代码时,我们重写生命周期方法的基本实现。我们进入已有的生命周期方法(已经附加过代码的方法),然后添加我们自己的代码。我们在自己方法里调用基础方法,以此保证在执行我们自己代码之前执行原始的基础代码。我们将在下一节看到例子。
Activity生命周期是Android中一个重要又复杂的部分,在此我们将不继续深入了解。如果在你完成入门系列后,你需要知道更多关于Activity的内容,我们建议阅读:原文:Activity Lifecyle。下面,我们关注Activity生命周期中的OnCreate
阶段。
OnCreate方法
Android在创建Activity时,调用Activity中的OnCreate
方法 —— 在界面呈现给用户之前。我们可以重写OnCreate
生命周期方法来创建视图,以及为用户准备Activity内容:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// Additional setup code will go here
}
在Phoneword示例中,我们在OnCreate
中处理的首要事情是将我们创建的设计界面展示给用户。为了加载UI,我们调用SetContentView
方法,并将设计文件(Main.axml
)的资源名称传给它。我们的设计图用Resouce.Layout.Main
来定位:
SetContentView (Resource.Layout.Main);
当MainActivity
启动时,它会以Main.axml
内容为基础创建视图。注意,我们已经将设计界面与我们的Activity进行了匹配—— Main.axml文件是针对MainActivity的设计。从Android的角度看,者不是必须的,但是当我们添加更多的界面到应用时,我们会发现如此格式的命名方式有助于我们将码代码与界面设计文件联系到一块。
一旦我们设置好界面设计文件,我们可以查找对应的控件。查找控件的方法是调用FindViewById
方法并传入控件的资源id参数:
EditText phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText);
Button translateButton = FindViewById<Button>(Resource.Id.TranslateButton);
Button callButton = FindViewById<Button>(Resource.Id.CallButton);
现在我们有设计界面中控件的对象,我们可以通过他们进行用户交互响应。
响应界面交互
在Android中,Click
事件监听的是用户触碰。在我们的app中,我们使用了一个lambda表达式处理Click
事件,但是我们还可以使用delegate委托或一个事件处理程序 。我们最终的 TranslateButton 的代码大概如下:
translateButton.Click += (object sender, EventArgs e) =>
{
// Translate user’s alphanumeric phone number to numeric
translatedNumber = Core.PhonewordTranslator.ToNumber(phoneNumberText.Text);
if (String.IsNullOrWhiteSpace(translatedNumber))
{
callButton.Text = "Call";
callButton.Enabled = false;
}
else
{
callButton.Text = "Call " + translatedNumber;
callButton.Enabled = true;
}
};
Phoneword中用到的额外概念
本指南中还有几个在Phoneword应用中使用,却没有介绍的概念。其中有包括以下内容:
-
修改按钮文本 —— 通过修改 Button 的 Text 属性来改变 Button 的文本。如下,将
callButton
的文本改为Call
:callButton.Text = "Call";
-
启用和禁用按钮 —— 按钮 可以是可用或不可用状态。不可用的 按钮 不会响应用户的输入。禁用
callButton
的代码如下:callButton.Enabled = false;
关于更多按钮的相关信息见:原文:Android Buttons guide
-
显示弹出框 —— 当用户点击 Call 按钮时,我们的应用会显示一个弹出框——用于用户确认或取消拨打。我们使用了 Alert Dialog Builder 来创建弹出框。我们的弹窗由一个
Neutral
类型按钮(用于拨打电话)和一个Negative
类型的按钮(用于取消拨打电话)组成,如下代码所示:var callDialog = new AlertDialog.Builder(this);
callDialog.SetMessage("Call " + translatedNumber + "?");
callDialog.SetNeutralButton("Call",
delegate
{
// Create intent to dial phone
});
callDialog.SetNegativeButton("Cancel", delegate {}); // Show the alert dialog to the user and wait for response.
callDialog.Show(); -
使用Intent启动电话app —— 当我们确认拨打电话后,我们调用一个 Intent 来启动系统的电话app,并将我们需要拨打的号码传入,如下代码所示:
var callIntent = new Intent(Intent.ActionCall);
callIntent.SetData(Android.Net.Uri.Parse("tel:" + translatedNumber));
StartActivity(callIntent);
在Hello,Android Multiscreen中我们将更加深入的介绍Intent。在那个指南中,我们会学到如何使用Intent启动另外的Activity(界面),甚至是启动其他应用 。
测试,部署和收尾处理
XamarinStudio和Visual Studio都提供了多种方式来测试和部署应用。本节包含内容有:调试选项、在设备上演示应用测试,以及介绍为不同的屏幕分辨率创建app图标的工具。
调试工具
有些时候,应用代码中的问题很难诊断出来。为了帮助分析复杂代码中的问题,我们提供以下内容:原文:Set a Breakpoint,原文:Step Through Code, 或 原文:Output Information to the Log Window。
部署到设备
模拟器是用于部署和测试应用的好工具,但是用户不会再模拟器中使用最终app。我们应该及时并常常在真实设备上测试应用。
在Android设备可以被用于测试应用前,需要进行一些开发配置。关于准备开发设备的详细内容见:原文:Set Up Device for Development。
一旦设备配置好,我们可以将其插入到计算机,然后开发工具中可以选择此设备,并启动应用:
这样应用会自动部署到设备并运行:
为不同屏幕分辨率设置图标Icon
Android设备有不同的屏幕大小和分辨率,因此图片不会再所有界面都看起来好。例如,以下是低像素图标在高分辨率的Nexus 5上的截图。可以看到它比周围的图标要模糊:
为了解决这个问题,可以将不同分辨率的图标文件添加到Resources文件夹。Android提供了不同版本的drawable文件夹来处理不同像素的图像,其中包括:ldpi —— 低分辨率使用,mdpi —— 中等分辨率使用,hdpi —— 高分辨率使用,xhdpi 和 xxhdpi —— 用于很高分辨率的屏幕使用。不同大小的图标存储在对应的 drawable-* 文件夹中:
Android会在不同屏幕上选择对应分辨率的图标:
生成自定义图标
不是每个人都有专门的设计人员来创建自定义图标和初始启动页面的。下面有些备用方案可以用于自定义应用插图:
- Android Asset Studio —— 一个基于网页浏览的Android图标生成器,同时还链接了一些其他有用的社区工具。最好在Chrome中操作。
- Visual Studio —— 可以直接在IDE中为你的应用创建一些简单的图标
- Glyphish —— 高品质的图标集(可免费下载或购买)
- Fiverr —— 选择设计师来为你创建图标,最低价 $5。可能命中也可能错过,但如果你急需设计图标,这是一个很好的去处。
关于更多图标尺寸和要求的详细信息见:原文:Android Resources、译文:Xamarin.Android应用基础——Android资源介绍
总结
至此,你就可以对Xamarin.Android应用有一个比较深入的理解,同时对创建所需的工具也有一定的了解。在下一节入门系列教程中,我们将介绍多屏幕应用,同时介绍Android中更高级的架构和概念。
译:奇葩史