你的位置:首页 > 操作系统

[操作系统]【Android】第4章(1) Android项目的基本结构


分类:C#、Android、VS2015;创建日期:2016-02-06

第4章 UI设计基础

第3章虽然通过百度地图应用展示了你可能感兴趣的内容,但是,如果你是一个初学者,一开始就看懂和理解代码可能会非常费劲。为了解决此问题,从这一章开始,本模块将从最基本的内容讲起,带你逐步进入用C#进行Android应用开发的乐园。

4.1 Android项目的基本结构

要用C#开发Android应用程序,首先需要对项目的基本结构有一个感性认识。如下图所示:

image

1、AndroidApp入口

Android应用程序使用的是单一入口,源程序中并不能一眼看出程序从哪开始运行,当应用程序加载到内存中时,Android操作系统会自动从内部自定义的入口处开始运行该应用程序。这种独特的架构可让程序员设计的代码直接和Android操作系统交互,但其缺点也很明显:即使一个非常简单的程序,也会变得很复杂。

为了方便找到程序入口点,当新建一个Android项目时,默认情况下,在MainActivity.cs文件的特性声明中通过“MainLauncher = true”表示程序从这个Activity开始执行:

[Activity(Label = "myDemos", MainLauncher = true)]

public class MainActivity : Activity

{

     //……

}

注意MainActivity.cs的前缀,一般表示它控制的是布局文件Main.a

实际上,你可以把“MainLauncher = true”放到任何一个继承自Activity的类中。总之,你将其放到哪个类的特性声明中,程序就从哪个Activity开始执行。

2、组件(Components)

在Android应用程序中,每个组件都是一个独立的模块,但并不是所有组件都是用户进入程序的真实入口,其中一些要依赖于其它组件。

Android内置了四种不同的应用程序组件:Activity、Service、Content Provider和Broadcast recevicer。除此之外,还可以自定义组件并将其保存到项目的Components文件夹下。

在后面的章节中,还会专门介绍这些内容,这里你只需要记住真正掌握Android应用开发技术,必须理解这些组件的含义和具体使用场合即可。

3、附件(Assets)

Assets文件夹包含了运行App需要的所有原始文件。该文件夹下可保存任意类型的文件:text、

下面的代码演示了如何读取Assets下的.txt文件:

using Android.App;using Android.OS;using Android.Widget;using System.IO;namespace MyTestProj{  [Activity(Label = "Activity1")]  public class Activity1 : Activity  {    protected override void OnCreate(Bundle savedInstanceState)    {      base.OnCreate(savedInstanceState);      base.OnCreate(savedInstanceState);      var textView1 = new TextView(this);      string content;      using (StreamReader sr = new StreamReader(Assets.Open("readme.txt")))      {        content = sr.ReadToEnd();      }      textView1.Text = content;      SetContentView(textView1);    }  }}

 

4、资源(Resources)

一个Android App由代码、资源文件以及自定义的组件构成。

资源文件保存到Resources文件夹下,包括图片,音频文件,以及任何与程序可见内容相关的东西。例如,自定义的动画、菜单、风格、颜色以及由.a

(1)基本概念

Resources文件夹下保存的资源不包括代码文件,而是指随项目一起编译和打包的除了代码文件之外的其他文件,如声音、视频、图像、字符串、布局文件等。

image

将资源单独组织的优点是:代码分离,这样就可以适用于多平台,同时也能在编译时进行检查,并在编译通过后为键入C#代码提供智能提示。

使用资源可使修改程序的特征变得很容易,同时不必修改代码。而且通过可选择的资源集合,能为不同的设备配置优化程序(例如不同的国家语言和不同的屏幕尺寸等)。

系统搭建工具会自动为Android项目使用的每一个资源都定义一个唯一的整型ID,程序通过ID获得代码中的资源或者.

分隔资源的一个重要能力是为不同的设备配置提供可选择的资源文件。例如,在

Android支持很多不同的修饰符以支持可选的资源。这些修饰符都是被加入到资源目录名中的简短字符串。这样定义是为了定义设备的特定配置,以保证这个目录下的资源可能会被使用到。

(2)常用资源

项目中常用的资源文件夹如下。

(a)图片资源

Drawable:保存通用的图片文件。

drawable-ldpi:保存低分辨率手机专用的图片文件。

drawable-mdpi:保存中等分辨率手机专用的图片文件。

drawable-hdpi:保存高分辨率手机专用的图片文件。

drawable-xdpi:保存超高分辨率手机专用的图片文件。

drawable-xxdpi:保存超超高分辨率手机专用的图片文件。

(b)布局文件

layout文件夹:用于保存所有界面文件(包括带设计界面的.a

Main.a

(c)字符串资源文件

Values文件夹:存放用字符串描述的资源文件信息(strings、integers、colors等),这些都是文本资源,在文件夹中有一些约定的文件名称。(具体内容待以后详解)

5、默认的资源类型

下表列出了默认的所有资源类型及其描述:

image

下面用中文介绍一下这些文件夹的含义(用到相关文件时,在项目的Resources文件夹下创建对应的子文件夹即可)。

animator

描述属性动画的

注:Android的属性动画和WPF的属性动画的用法非常相似,只要学会其中一种,很快就会另一种的用法。

如果你对属性动画不熟悉,可参考对“属性动画”介绍比较详细的C# 系列教材:“十二五国家级规划教材《C#程序设计及应用教程》(第3版,马骏主编,人民邮电出版社)”,该书对WPF提供的属性动画的用法介绍的非常详细,也有对应的完整示例,很值得初学者阅读。

anim

描述补间动画(tween animations)的

color

描述颜色状态列表的

drawable

Drawable resources(可绘制资源)是编译到应用程序中的图像资源,这些资源可通过API去调用或引用其他的

说明:9-Patch图像(*.9.png)的含义及用法见本博客第5章的图像示例。

layout

如果希望某个文件包含预览界面,将扩展名“.

menu

raw

原始的二进制形式保存的任意文件。该文件夹下的这些文件都会被编译到二进制格式的 Android 应用程序中。

values

6、引用资源的方式

当将资源文件添加到项目中时,管道会自动将该资源描述添加到资源中,并自动生成对应的类(保存在Resource.designer.cs文件中),自动生成的类会为每个资源自动分配一个唯一的ID。

有两种存取和管理资源的方式:

  • 用C#代码引用资源。
方式1--在C#代码中引用资源

格式:@[<PackageName>.]Resource.<ResourceType>.<ResourceName>

例如:

SetContentView(Resource.Layout.Main);EditText phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText);

方式2--在

格式:@[<PackageName>:]<ResourceType>/<ResourceName>

例如(见Main.a

<??><LinearLayout ="http://schemas.android.com/apk/res/android"     android:orientation="vertical"     android:layout_width="fill_parent"     android:layout_height="fill_parent">  <ImageView android:id="@+id/myImage"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:src="@drawable/flag" /></LinearLayout>

7、备用资源(Alternate Resources)

备用资源也是保存在Resources文件夹下,子文件夹的格式为:

<ResourceType>-<Qualifier>

即:<资源类型>-<限定标识符>

例如:drawable-hdpi

当有多个限定符时,各限定符之间用短划线分隔。

限定符必须按下表列出的顺序出现(该表实际是按优先级从高到低排列):

image

 

 

 

 

image

image

例如,v11的目标是API level 11 (Android 3.0)设备。

下面是截图表格中各限定符的含义。

MCC、MNC

手机的国家码(MCC):手机的SIM卡提供商。

移动网络码(MNC):手机连接到的网络供应商。

尽管本地化目标可以使用用于移动设备的国家码,但是仍建议使用资源限定符来限定它。例如:美国(U.S)的资源限定符是 mcc310-mnc026

MCC的完整编码详见下面的网站:http://mcclist.com/

Language

两字母的ISO 639-1国家语言编码以及可选的两字母的ISO-3166-alpha-2区域编码。 如果同时提供这两个限定符,用“-r”分隔。

例如:对于French-Canadian locales,使用的资源限定符为:fr-rCA

完整的语言和区域编码见“Codes for the Representation of Names Of Languages and Country names and code elements”。

Smallest Width

限定屏幕执行时使用的最小宽度。例如:sw320dp 表示目标设备的高和宽最小说320dp。

Available Width、Available Height

Available Width:屏幕最小宽度,格式:w<N>dp,其中N表示与像素无关的宽度。当用户旋转屏幕时会改变该值。例如:w720dp 表示目标设备的最小宽度为720dp

Available Height:屏幕最小高度,格式:h<N>dp,其中N表示与像素无关的宽度。当用户旋转屏幕时会改变该值。例如:h720dp 表示目标设备的最小高度为720dp

Screen aspect

指屏幕的宽高比,而不是屏幕的放置顺序(纵向和横向)。其值有两个:long(表示宽屏幕)、notlong(表示非宽屏幕)。

Screen Orientation

屏幕放置顺序,Portrait(纵向放置)或者landscape(横向放置)。该值可在应用程序的生命周期中改变。取值有:port、land

Dock mode

设备在 car dock或者 desk dock 中。API 8(Android 2.2.x)开始提供。取值有:car、desk

Night mode

应用程序是否在夜间模式下运行。此限定可给开发者在应用程序生命周期中提供优化选项。API level 8 (Android 2.2.x)开始提供。

可能的值:night、notnight

Screen pixel density (dpi)

物理屏幕的像素数,通常用dpi表示。可能的值有:

ldpi – 低分辨率屏幕

mdpi – 中等分辨率屏幕

hdpi – 高分辨率屏幕

xhdpi – 超高分辨率屏幕

nodpi – 资源不可缩放

tvdpi – 在mdpi和hdpi之间

Touchscreen type

限定设备是哪种触摸屏。可能的值有:notouch (无触摸功能)、stylus(适用于手写笔的电阻式触摸屏)、finger(手指触摸)

Keyboard availability

限定哪种键盘可用。可在应用程序的生命周期中改变它。可能的值有:

keysexposed – 该设备有可用的键盘。如果软键盘不可用,则当【硬件键盘】设置打开时仅使用硬键盘。

keyshidden – 设备没有硬键盘,而且软键盘也隐藏。即:软件没有可以用的键盘。

keyssoft –设备有可用的软键盘。

Primary text input method

限定哪种硬件键盘可用于输入。可能的值有:

nokeys – 无可用的用于输入文本信息的硬件键盘。

qwerty – 有可用的qwerty键盘。

12key – 有可用的12-键(12-key)硬件键盘。

Navigation key availability

用于当“5-way”或者“d-pad (directional-pad)”导航键可用的情况。可在应用程序生命周期中改变。可能的值有:

navexposed – 用户可以使用导航键。

navhidden – 导航键不可用。

Primary non-touch navigation method

设备提供的可用导航键。可能的值有:

nonav – 仅能通过触摸屏幕导航。

dpad – 有可用的“d-pad (directional-pad)”导航。

trackball – 设备有一个“trackball”用于导航。

wheel - (不常见)有一个或多个可用的定向轮

Platform version (API level)

设备支持(supported)的API级别。格式:v<N>

下图列出了Android的判断规则:

image

8、权限设置与管理(AndroidManifest.

清单(Manifest)可以定义应用程序及其组件的结构和元数据。

AndroidManifest.

该文件的功能类似于网站中的Web.conig文件。

在AndroidManifest.

image

 

设置后,它会自动更新项目中Properties文件夹下的AndroidManifest.

在Android系统能够启动一个程序组件之前, 系统必须通过读取程序的AndroidManifest.

除了声明程序组件外,这个配置文件还做一些其它的工作,例如:

  • 确定程序需要哪些用户权限,例如网络访问或者读取用户的联系人。
  • 声明程序需要的最小的 API Level 这个要参照程序都使用了哪些API。
  • 声明程序使用或要求的硬件和软件特性,例如相机,蓝牙服务,或者多点触屏。
  • 程序需要链接的API类库(除Android framework API之外的类库),例如 Google Map类库。

但是,如果用C#来开发,“直接在AndroidManifest.

当然,如果你希望直接在该文件中添加声明,也可以这样做。换言之,C#开发给你提供了多种声明清单的方式,你只需要按自己的习惯去选择一种合适的方式即可。这些方式有:

  • 在AndroidManifest.
  • 通过项目的属性窗口选择,然后让编译器自动将合适的代码添加到AndroidManifest.
  • 在AssemblyInfo.cs文件中声明,然后让编译器自动自动将合适的代码添加到AndroidManifest.
  • 通过在类上方添加特性声明来声明,然后让编译器自动自动将合适的代码添加到AndroidManifest.

通过这些方式,你就拥有了最大的灵活性,同时也是代码看起来简洁而直观,

9、CPU架构(CPU Architectures)

VS2015调试模式(Debug)使用的是可适应多种CPU架构的模式,发布模式(Release)用于选择某种具体型号的手机,然后部署。

(1)如何指定支持的CPU架构

在调试状态(Debug)下,下面的两个选项默认是选中的:

image

这两个选项选中后。可防止调试时指定某种具体的CPU架构(CPU Architectures),即在下面的配置中,下面这些选项是不可更改的:

image

 

通常情况下,实际发布应用程序时需要明确配置使用的CPU体系结构或架构。当更改为发布(Release)模式时,它会自动不勾选“Use Shared Runtime”和“Use Fast Delployment…”复选框,这样一来,上图中的选项就可选了。

Xamarin.Android提供下面的架构:

  • armeabi – 基于ARM的CPU系列,提供了不低于ARMv5TE结构的指令集。注意armeabi不是线程安全的而且不能用于多CPU的设备。
  • armeabi-v7a – 这种CPU支持硬件浮点运算和多CPU(SMP)设备。注意armeabi-v7a的机器码无法在ARMv5设备上运行。
  • arm64-v8a –这是一种基于64-bit ARMv8架构的CPU。
  • x86 – 这种CPU提供x86 (or IA-32)指令集。该指令集等价于奔腾Pro(Pentium Pro),包括MMX, SSE, SSE2,以及SSE3指令集。
  • x86_64 CPUs提供64-bit的x86指令集。

在Release模式下,Xamarin.Android默认指定的是armeabi-v7a,其性能比armeabi高。如果发布目标是64-bit ARM平台(例如Nexus 9),此时需要选择arm64-v8a。如果发布到x86设备,就选择x86,如果发布目标是64-bit的CPU架构,就选择x86_64。

注意:由于在64位架构上可运行32位程序(例如Nexs 9就是64-bit ARM设备),因此,发布到64位手机设备上的时候,不是必须选择arm64-v8a或x86_64,仍然可以继续选择32位架构,这样做的优点是可避免应用程序占用过多的内存。

(2)多平台目标(Targeting Multiple Platforms)

面向多平台的优点是可同时调试多种CPU,缺点是这会导致.apk文件很大,如果希望减少.apk文件的大小,发布时只选择一个平台就行了。

注意:虽然在Xamarin.Android 5.1.x或更高版本中也可以体验64位的功能,但实际发布时并不使用它。