创建第一个Android应用程序 HelloWorld
按照博客的进程,今天应该进行程序编写啦,下面让我们开写一个简单的HelloWorld程序。
提示:这里对于如何使用Eclipse创建一个Android程序就不多讲啦,不会的同学可以去查阅相关文档。
- 程序清单文件hello_world.xml
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".HelloWorldActivity" > <TextView android:id="@+id/show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_alignParentTop="true" android:text="@string/hello_world" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/show" android:text="单击我" android:onClick="clickHandler"/> </RelativeLayout>
上面XML文档的跟元素是RelativeLayout,它代表一个相对布局,在该界面布局里包含如下两个UI控件。
- TextView:代表一个文本框
- Button:代表一个普通按钮
①android:id:该属性指定了该控件的唯一标识,在Java程序中可以通过findViewById("id")来获取指定的Android界面组件。
②android:layout_width:指定该界面组件的宽度。如果该属性值为match_parent,则说明该组件与其父容器具有相同的宽度;如果该属性值为wrap_content,则说明该组件宽度取决于它的内容——能包裹它的内容即可。
③android:layout_height:指定该界面组件的高度。如果该属性值为match_parent,则说明该组件与其父容器具有相同的高度;如果该属性值为wrap_content,则说明该组件的高度取决于它的内容——能包裹它的内容即可。
2. 程序清单文件HelloWorldActivity.java
package org.crazyit.helloworld; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.*; import android.widget.*; public class HelloWorldActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.hello_world); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.hello_world, menu); return true; } public void clickHandler(View source) { //获取界面ID为R.id.show的文本框 TextView tv=(TextView)findViewById(R.id.show); //改变文本框的文本内容 tv.setText("Hello Android-你好现在时间为:"+new java.util.Date()); } }
对于上面的代码做如下分析:
- 设置该Activity使用hello_world.xml文件定义的界面布局作为用户界面。
- 定义了一个clickHandler()方法作为按钮事件处理方法——在处理方法中改变ID为R.id.show的文本框的内容。
3. 通过ADT或者真机运行应用(此处不再赘述)
4. Android应用结构分析
以上代码有两个疑问:
- findViewById(R.id.show);代码中的R.id.show是什么?从哪里来?
- 为何setContentView(R.layout.hello_world);代码设置使用hello_world.xml文件定义界面布局文件?
带着这些疑问我们进一步“追根究低”
找到我们创建的HelloWorld程序所在的目录:可以看到如下几个必要的文件夹
上面的文件结构中res目录,src目录、AndroidManifest.xml文件是Android项目必须的,其他目录、其他文件都是可选的。
- res目录存放Android项目的各种资源文件,比如子目录layout存放各种界面布局文件,values子目录则存放各种XML格式的资源文件,例如字符串资源文件:string.xml;颜色资源文件:colors.xml;尺寸资源文件:dimens.xml。drawable-ldpi、drawable-mdpi、drawable-hdpi、drawable-xhdpi这4个子目录分别用于存放低分辨率、中分辨率、高分辨率、超高分辨率的4种图片文件。
- src目录只是一个普通的、保存Java源文件的目录。
- AndroidManifest.xml文件是安卓项目的系统清单文件,它用于控制Android应用的名称、图标、访问权限等整体属性。除此之外Android应用的Activity、Service、ContentProvider、BoradcastRecevier这4大组件都在该文件中配置。
- 除此之外还可以看到一个build.xml文件这是Android为该项目提供的一个Ant生成文件。如果没有该文件可以用切换到项目生成的跟目录敲入命令:android update project -n <项目名称> -p <项目所在的位置> 生成build.xml文件 ,如图
上图中HelloWorld为项目名称,“.”代表当前路径
- 在项目的生成目录中启动ant命令,下面对ant命令简单介绍一下
Ant是一个非常简答、易用的项目生成工具。对绝大部分Java开发者来说,使用Ant应该是一项基本的技能。现在可以登录到http://ant.apache.org/下载后在环境变量中配置后相关路径即可使用
- clean:清除项目生成的内容——也就是恢复原来的样子。
- debug:打包一个调试用的Android应用的APK包,使用debug key进行签名。
- release:打包一个发布用的Android应用的APK包。
- test:运行测试。要求该项目必须是一个测试项目。
- install:将生成的调试用的APK包安装到模拟器上。
- uninstall:从模拟器上卸载该应用程序。
先执行ant release命令来发布该项目,发布完成后到Hello World目录下出现了两个子目录。
①bin:该目录用于存放生成的目标文件,如Java的二进制文件、资源打包文件(.ap_后缀)、Dalvik虚拟机的可执行文件(.dex后缀)等。
②gen:该目录用于保存自动生成的、位于Android项目包下的R.java文件。上面我们编写Android程序代码时多次使用了R.layout.main、R.id.show、R.id.ok......现在明白R是什么了,它原来是Android项目自动生成的Java类。
- 自动生成的R类
/* AUTO-GENERATED FILE. DO NOT MODIFY. * * This class was automatically generated by the * aapt tool from the resource data it found. It * should not be modified by hand. */ package org.crazyit.helloworld; public final class R { public static final class attr { } public static final class dimen { /** Default screen margins, per the Android Design guidelines. Customize dimensions originally defined in res/values/dimens.xml (such as screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. */ public static final int activity_horizontal_margin=0x7f040000; public static final int activity_vertical_margin=0x7f040001; } public static final class drawable { public static final int ic_launcher=0x7f020000; } public static final class id { public static final int action_settings=0x7f080002; public static final int button1=0x7f080001; public static final int show=0x7f080000; } public static final class layout { public static final int hello_world=0x7f030000; } public static final class menu { public static final int hello_world=0x7f070000; } public static final class string { public static final int action_settings=0x7f050001; public static final int app_name=0x7f050000; public static final int hello_world=0x7f050002; } public static final class style { /** Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. Base application theme for API 11+. This theme completely replaces AppBaseTheme from res/values/styles.xml on API 11+ devices. API 11 theme customizations can go here. Base application theme for API 14+. This theme completely replaces AppBaseTheme from BOTH res/values/styles.xml and res/values-v11/styles.xml on API 14+ devices. API 14 theme customizations can go here. */ public static final int AppBaseTheme=0x7f060000; /** Application theme. All customizations that are NOT specific to a particular API-level can go here. */ public static final int AppTheme=0x7f060001; } }
同过R.java类中的注释可以看出,R.java文件是有aapt工具根据应用中的资源文件来自动生成的,可以包R.java理解成Android应用的资源字典。
aapt生成R.java文件的规则主要是如下两条:
①每类资源对应R类的一个内部类
②每个具体的资源对应于内部类的一个public static final int 类型的Field。
5、res目录说明
Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源。已/res/values/string.xml文件来说,该文件内容十分简单,它只是定义了一条条的字符串长量,如以下代码所示:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">HelloWorld</string> <string name="action_settings">Settings</string> <string name="hello_world">Hello world!</string> </resources>
上面的资源文件中定义了一个字符串常量,常量的值为HelloWorld,该字符串常量的名称为app_name。一旦定义了这份资源文件之后,Android项目允许分别在Java代码、XML代码中使用这份资源文件中的字符串资源。
①在Java代码中使用资源
为了在Java代码中使用资源,AAPT会为Android项目自动生成一个R.java文件,R类里为每份资源定义了一个内部类,其中每个资源项对应于内部类里一个int类型的Field。例如上面的字符串资源文件对应于R.java里面的内容:
public static final class string { public static final int app_name=0x7f050000; }
借助于AAPT工具自动生成R类的帮助,Java代码可以通过R.string.app_name来引用到“HelloWorld”字符串常量。
②在XML文件中使用资源
在XML文件中使用资源更加简单,只要按如下格式来访问即可:
@<资源对应的内部类的类名>/<资源项的名称>
例如我们要访问上面的字符串资源中定义的“HelloWorld”字符串常量,则使用如下形式来引用即可:@string/app_name
但有一种情况例外,当我们在XML文件中使用标示符时——这些标示符无须使用专门的资源进行定义,直接在XML文档中按如下格式分配标示符即可:
@+id/<标示符代码>
例如使用如下代码为一个组件分配标示符:
android:id="@+id/ok"
上面的代码为该组件分配了一个标示符,接下来就可以在程序中引用该组件了。
如果希望在Java代码中获取该组件,通过调用Activity的findViewById(R.id.ok)方法即可实现。
如果希望在XML文件中获取该组件,则可通过资源引用的方式来引用它,语法如下:
@id/<标示符代码>
6、Android应用的清单文件:AndroidManifest.xml
AndroidManifest.xml清单文件是每个Android项目所必需的,它是整个Android应用的全局描述文件。AndroidManifest.xml清单文件说明了该应用的名称、所使用的图标以及包含的组件等。
AndroidManifest.xml清单文件通常可以包含如下信息:
- 应用程序的包名,该包名将会作为该应用的唯一标识。
- 应用程序所包含的组件,如Activity、Service、BroadcastReceiver和ContentProvider等
- 应用程序兼容的最低版本。
- 应用程序使用系统所需的权限说明。
- 其他程序访问该程序所需的权限说明。
下面是一份简单的AndroidManifest.xml清单文件。
<?xml version="1.0" encoding="utf-8"?> <!-- 指定该Android应用的包名,该包名可用于唯一的表示该应用 --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.crazyit.helloworld" android:versionCode="1" android:versionName="1.0" > <!-- 声明该应用本身需要打电话的权限 --> <uses-permission android:name="android.permission.CALL_PHON" /> <!-- 声明该应用本身需要发送短信的权限 --> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <!-- 指定Android应用标签、图标 --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- 定义Android应用的一个组件:Activity 该Activity的类为HelloWorld,并指定该Activity 的标签 --> <activity android:name="org.crazyit.helloworld.HelloWorldActivity" android:label="@string/app_name" > <intent-filter> <!-- 指定该Activity是程序的入口 --> <action android:name="android.intent.action.MAIN" /> <!-- 指定加载该应用时运行该Activity --> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
应用程序权限清单文件权限说明:此处待续