创建你的第一个应用程序
欢迎来到安卓应用开发!
本课将向你描述如何创建你的第一个安卓应用程序,你将学会如何创建一个android工程并将其作为一个可调试版本运行,并且你还会学到一些android应用设计的组件,包括如何创建一个简单的人机交互界面并通过事件机制与其交互。
在开始本课程之前,确保你已经配置好了android的开发环境,你需要:
1、 下载Android SDK。
2、 如果你使用的是Eclipse集成开发环境,你还需要安装ADT插件。
3、 通过SDK Manager下载最新版本的SDK相关工具。
创建一个Android工程
一个android工程包括你应用程序的所有源代码。通过Android SDK工具包提供的默认目录和文件可以很方便地创建一个android工程。
本课将向你描述分别用Eclipse的ADT插件和命令行的方式如何创建一个新工程。
使用Eclipse创建一个工程
1、 点击工具栏中的”New”
选项;
2、 在弹出窗口中打开Android文件夹,选择AndroidApplication Project,点击Next;
3、 如下图所示填写新建工程相关信息:
ApplicationName 是应用的名称,在本工程我们使用”My First App”作为其工程名;
ProjectName 是你的工程在Eclipse集成开发环境中显示的工程名称;
PackageName是你程序的包命名空间(包名命名同java编程语言的规范)。你的包名在Android 系统所有包名中必须是独一无二的。出于这个原因,包名通常是你所在组织域名的反转,在本工程中,你可以使用类似于”com.example.myfirstappp”作为你工程的包名,但你不能将使用这个名字的应用发布到Google Play上面。
MinimumRequired SDK是你应用所支持的最低android sdk的API版本,为了让你的应用支持更多的设备,在sdk版本能够支持你应用的核心功能的前提下你应该将你的应用的最低支持版本尽量降低。如果你应用的某项功能只能在最新的sdk版本中使用,你可以通过控制代码只在新版本的sdk中启用该功能,不要将该功能作为你工程的标配。
TargetSDK作为你测试程序的最高SDK版本,当发布了新的android sdk版本时,你应该在新版本sdk中测试你应用的可用性,并将该属性设置为最新的sdk版本以便充分利用新版本sdk的属性。
CompileWidth是你应用程序所编译的sdk版本,默认情况下,它应该是你sdk中的最新版本,但你仍然可以通过旧版本的sdk编译你的程序。
Theme 指定了你应用的UI风格。
点击Next
4、 在下一屏中保持默认选项并点击Next;
5、 在下一屏中可以帮助创建一个你app的桌面显示图标。
点击Next
6、 现在你可以选择一个activity模板开始开发你的app了,在本课程中,选择BlankActivity并点击Next;
7、 保持此Activity的所有默认选项并点击Finish。
到目前为止你已成功创建了一个工程,可以开始开发你的应用啦。
通过命令行工具创建一个工程
如果你不是使用带ADT的Eclipse开发环境,你同样可以通过SDK工具包的命令来创建一个android工程。
1、 切换目录到androidSDK的tools目录下;
2、 执行命令:”android list targets”,列出你所下载的所有可用SDK版本,查找你想通过其编译程序的SDK版本,标记目标ID,我们建议你选择最新的SDK版本作为你应用程序的编译版本,不过你仍然可以选择旧版本SDK编译,但是使用最新SDK版本编译可以让你的应用支持最新SDK版本的设备。
3、 执行” android create project --target <target-id>--name MyFirstApp --path <path-to-workspace>/MyFirstApp --activityMainActivity --package com.example.myfirstapp”命令,在目标列表中选择一个id代替<target-id>,选择一个你工程的存放路径代替<path-to-workspace>。
到目前为止,通过命令行已经成功创建了一个android工程,你可以进行下一步操作了。
运行你的应用程序
如果你已按照上一节课程成功创建了一个Android 工程,通过工程默认包含的”Hello World”源文件你可以立即运行你的应用程序。
如何运行你的应用程序取决于两件事:你用的是android真机还是Eclipse模拟器,本课将向你描述通过Eclipse和命令行工具如何分别在真机和android模拟器中安装你的应用。
在运行你的程序之前,你应该对你工程的目录和文件列表有所了解。
AndroidManifest.xml
清单文件描述了应用程序的基本特征,并且定义了所用到的每个组件。在你阅读了更多的培训文档后,你将在这个文件中了解到各种声明的意思。
<uses-sdk>是清单文件必须包含的一个标签,它通过设置”android:minSdkVersion”和”android:targetSdkVersion”属性指定了你的应用使用于在哪些SDK版本中使用,在本例中,它是这样子的:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
...
</manifest>
你应该将”android:targetSdkVersion”尽量设置为最新的sdk版本并在这个版本中测试你的应用。
src/
应用的主要源文件目录,默认情况下,它会包含当你点击应用图标时进入的主activity源文件。
res/
包含关于应用程序资源文件的一系列子目录,举例说明:
drawable-hdpi/
存放高分辨率屏幕下的一些图片资源,其它drawable文件夹下包含其它分辨率屏幕下的图片资源。
layout/
定义程序每个节目的布局。
values/
包含一些文件类型为xml的资源文件的集合,比如字符串和颜色属性的定义。
当你运行本课所创建的应用时,默认主窗口中会显示一个”Hello World”的字符串,虽然除了这个字符串没有显示其它任何东西,但重要的是你明白了在你正式开发之前如何运行一个应用。
在真机上运行
如果你有一个android真机,通过如下步骤你可以在你的真机上安装并运行第一个android应用:
1、 通过USB连接你的设备和电脑,如果你使用的是Windows操作系统,你需要安装USB驱动之后才能使真机和PC通信。
2、 在你的设备上打开”USB debugging”模式。
在运行Android3.2或者更老版本的设备上,你可以发现”Settings>Applications>Development”这个选项。
在Android 4.0以及更新版本的设备上,该选项在”Settings>Developeroptions”下
注意:在Android 4.2及更新版本的设备上,”Developer options”选项默认处于隐藏状态,可以通过”Settings>About phone”,并点击”Build number”七次后返回上一个屏幕可以找到”Developer options”选项。
在Eclipse上切换到该程序:
1、 打开工程中的某一个文件并点击工具栏上的”Run”
按钮;
2、 在”Run as”窗口出现后,选择”Android Application”并点击”OK”;
进行如上操作后,Eclipse将会在你的设备上安装并启动你所运行的应用。
或者通过命令行的方式运行你的应用:
1、 切换到你android工程目录下,并执行”ant debug”命令;
2、 确保在环境变量的”Path”中已经添加droid SDK”platform-tools”目录,然后执行”adb install bin/MyFirstApp-debug.apk”
3、 在你设备上找到刚才安装的应用并打开它。
在模拟器上运行
无论你是用Eclipse还是命令行,在模拟器上运行你的应用之前你必须创建一个android模拟器(AVD)。
通过如下步骤可以创建一个AVD:
1、 启动AndroidVirtual Device Manager:
a. 在Eclipse中可以通过点击工具栏的
按钮来启动AndroidVirtual Device Manager。
b. 如果是通过命令行启动,则先跳转到sdk安装目录的”tools/”目录下并执行”android avd”命令。
2、 在弹出的AndroidVirtual Device Manager界面点击”New”;
3、 填写AVD的名称、sdk版本、SD卡大小和皮肤等详细信息;
4、 点击”Create AVD”;
5、 在” Android Virtual Device Manager”中选择新建的AVD模拟器并点击”Start”;
6、 在模拟器成功启动后,解锁模拟器。
通过Eclipse在模拟器上运行应用:
1、 打开你需要运行的工程并点击工具栏的”Run”
按钮;
2、 在”Run as”窗口中选择”Android Application”并点击”OK”。
执行上述步骤之后Eclipse就会在模拟器中安装并运行你需要运行的程序。
或者可以通过命令行在模拟器上运行你的应用:
1、 切换到android工程目录下并执行”ant debug”命令;
2、 确保在环境变量的”Path”中已经添加droid SDK”platform-tools”目录,然后执行”adb install bin/MyFirstApp-debug.apk”
3、 在模拟器上,找到刚才安装的应用并启动它。
创建一个简单的交互界面
Android应用的图形界面是由View和ViewGroup组成的,View是常用的UI组件,比如按钮和文本显示控件;而ViewGroup是控制其子视图显示属性的,比如是按Grid还是List方式显示。
你可以通过用android提供的通过xml文件布局应用界面来轻松地设计你应用的界面。
在本课中,你将创建一个带TextField和Button的xml的布局文件,在接下来的课程中,你需要在点击按钮时接受消息并将Text Field信息发送到另一个窗口。
创建一个线性布局
在”res/layout/”文件夹下打开”activity_amin.xml”文件。
注意:在Eclipse中,当你打开一个布局文件时,首先映入眼帘的是这个布局的图形布局编辑器,这个一个可以通过拖动各组件来创建布局的WYSIWYG工具。在本课中,直接在xml文件中修改布局,所以点击activity_mainl.xml文件底部的xml布局表项切换到XML文件编辑器。
在你创建应用时,默认的BlankActivity模板的布局“activity_main.xml“中是一个”Relativelayout“根布局和一个”TextView”子视图。
首先,删掉<TextView>标签并且将根布局由相对布局”RelativeLayout”改成现形布局”<LinearLayout>”,然后在根布局中添加”android:orientation”属性将线性布局设置为横向”horizontal”,完成后的xml布局文件是这样子的:
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="horizontal" >
</LinearLayout>
线性布局是ViewGroup的子类,通过”android:orientation”属性设置其子视图为竖向或者横向布局,它的每一个子视图都是按照设置的显示方式进行显示。
每个视图都需要通过”android:layout_width”和”android:layout_height”这两个属性来指定其宽度和高度。
由于线性布局”LinearLayout”是该布局的根布局,所以应该将其宽高设置为”match_parent”来填充这个界面。
添加一个”TextField”
通过在根布局下添加一个<EditText>来创建一个可编辑的编辑框。
和其它视图一样,你必须制定EditText的相关属性,比如像这样:
<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
关于上面的这些属性解释如下:
android:id
该视图独一无二的id,相当于身份证,你可以在代码中使用这个id来访问与其对应的视图,比如实例化或者监听这个视图。
当你在xml文件中定义视图的id时,必须在其属性值中增加标记”@”,紧接着后面跟上”id”和资源id名称”edit_message”。
你还会注意到在”@”和”id”之间有一个”+”标记,它代表你是第一次指定这个视图的id,SDK工具将通过视图id的名称在”gen/R.java”这两个类里面指定一个整型值来关联视图。一旦你指定了这个资源的id,在之后使用到这个视图时就不需要使用这个”+”啦。
android:layout_width和android:layout_height
你可以通过指定它们的属性值为”wrap_content”而不是特定的数值来设置该组件的大小,你如你使用的是”match_parent”属性,”EditText”将会填充整个屏幕。
android:hint
当EditText没有输入任何文本时的默认显示文本,这种方式比在代码中通过硬编码设置默认显示字符串信息好。
添加字符串资源
当你需要在界面中添加文本时,你需要为视图指定字符串资源,字符串资源允许你在一个位置管理所有的文本,这样更利于查找和更新文本内容,特别是在应用国际化的时候。
默认情况下,在创建工程时会在”res/values”目录下创建一个”strings.xml”字符串资源文件,将”edit_message”字符串添加到这个文件中,并将其映射文本设置为”Enter a message”。
同时增加一个”Send”字符串,方便后面增加的button使用,起名字为”button_send”。
此时的strings.xml文件看起来是这个样子的:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My First App</string>
<string name="edit_message">Enter a message</string>
<string name="button_send">Send</string>
<string name="action_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
</resources>
添加一个按钮
在<EditText>标签下增加一个<Button>标签:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
同样的,将宽高都设置为”wrap_content”,这个button不需要指定其id属性,因为它不需要在代码中做任何编辑。
设置输入框的宽度为填充屏幕
按照上面的步骤操作后,EditText和Button都是根据内容来改变宽度的,如下图所示:
上面的布局中,按钮能够很好的工作,但是EditText就不是那么舒服了,因为用户有可能在输入框中输入很多内容。所以最好是让输入框的宽度填充满整个屏幕。你可以通过在LinearLayout标签中设置”android:layout_weight”属性。
Weight属性是一个指定每个视图在剩余空间中所占比重的整形数值。
所有视图的默认权值为0,所以在你只有一个视图的情况时将其weight设为一个大于0的数值时,它将填满整个空间,所以在此例中,将EditText的weight设置为1,Button的weight设置为0,即可达到编辑框在宽度上填满除按钮外的任何区域。
<EditText
android:layout_weight="1"
... />
为了使得在为view指定weight属性后有效,应将EditText的宽度设置为0。
<EditText
android:layout_weight="1"
android:layout_width="0dp"
... />
按照上述步骤后,布局文件看起来是这个样子的:
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="horizontal">
<EditText android:id="@+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
</LinearLayout>
这个主窗口的布局,所以现在你可以尝试运行并查看效果了。
在Eclipse中,点击工具栏的Run
按钮;
或者通过命令行,切换目录到你工程的根目录下,执行如下命令:
ant debug
adb install bin/MyFirstApp-debug.apk
接下来的课程将教会你如何响应按钮的点击事件。
启动另外一个窗口
在完成上述课程之后,你现在拥有一个只有一个窗口(一个编辑框和一个按钮)的应用。在本课中,将在这个窗口中添加一些代码,通过响应按钮点击事件跳转到下一个窗口中。
响应按钮点击事件
为了响应按钮的点击事件,打开”activity_main.xml”布局文件并为<Button>标签加上”android:onClick”标签属性:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage" />
此处的”android:onClick”属性值为”sendMessage”,它是在按钮被点击时系统在你窗口中回调的一个方法。
打开”MainActivity”类(在”src/”目录下)并添加如下回调方法:
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
// Do something in response to button
}
这需要导入如下API:
import android.view.View;
小技巧:在Eclipse中,按下”Ctrl+Shift+O”可以导入该类需要的API(在Mac下的快捷键是”Cmd +Shift + O”)。
为了能够在按钮点击时系统准确地回调在<Button>标签中指定的”android:onClick”按键点击方法,该方法的属性必须准确,特别是该方法必须要有如下特征:
必须是共有方法;
有一个返回值;
带有一个View参数(就是那个被点击的视图啦)。
下一步,你可以在这个方法里面做点什么了。
建立一个Intent
Intent是一个在不同组件间提供消息绑定和传递的类(比如两个窗口之类的),它的意思是想要做某事。你可以用Intent做很多事情,但更多的时候它被用于启动另一个Activity.
在”sendMessage()”方法中,创建一个Intent来启动另一个窗口”DisplayMessageActivity”。
Intent intent = new Intent(this, DisplayMessageActivity.class);
实例化Intent的时候使用的是带两个参数的Intent构造方法。
Context,就是当前窗口的意思啦;
Class就是你打算要跳转到的窗口。
注意:当你使用Eclipse做如上操作的时候,你会因为”DisplayMessageActivity”还没有被创建而被系统提示此行代码有错,不管这个错误,接着往下学习吧。
Intent不仅仅可以启动另一个窗口,它还可以通过bundle在窗口间传递数据,在”sendMessage()”方法中,通过”findViewById()”方法实例化EditText,并将其text属性值绑定到Intent上。
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
注意:你现在需要导入”android.content.Intent”和”android.widget.EditText”,同时你需要定义一个”EXTAR_MESSAGE”常量属性。
Intent可以通过键值对携带一组不同类型的数据,在其使用的方法”putExta()”中,第一个参数为键值,第二个属性为需要传递的数据信息。
为了方便在下一个窗口中查找传递过去的属性,你应该使用一个公有的常量值作为上述方法的键值。如下所示:
public class MainActivity extends Activity {
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
...
}
将你当前窗口所在的包名作为监制的前缀是一个非常好的做法,这可以确保键值是独一无二的,特别是你和其它应用有交互的时候显得尤为重要。
启动第二个窗口
想要跳转到第二个窗口,你需要在第一个窗口中调用startActivity方法跳转,在调用这个方法后,系统将接受到这个回调并启动Intent指定的窗口。
现在,按钮点击回调方法看起来是这个样子的:
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
好啦,现在你需要创建一个”DisplayMessageActivity”来让这个代码工作啦。
创建第二个窗口
照猫画虎,创建第二个窗口:
1、 点击工具栏上的New按钮;
2、 在弹出的窗口中选择”Android”文件夹并且选择”AndroidActivity”,点击Next;
3、 选择”BlankActivity”并点击Next;
4、 接着填写窗口的详细属性:
Project:MyFirstApp
Activity name:DisplayMessageActivity
Layout Name:activity_display_message
Title:My Message
Hierarchial Parent:com.example.myfirstapp.MainActivity
Navigation Type:None
点击Finish
如果你是用的集成开发环境或者是命令行,你可以在src/目录下接着”MainActivity.java”创建第二个窗口类”DisplayMessageActivity.java”。
如果你是用的Eclipse创建的该类,打开它:
这个类已经自动生成了onCreate()方法;
同样自动生成了一个onCreateOptionsMenus()方法,但是在本例中我们不会用到它;
还会生成一个onOptionsItemSelected()方法来响应ActionBar的操作。
由于ActionBar只被API 11及以上的版本支持,所以你首先应该在getActionBar()方法中检查当前程序所使用的SDK版本,另外为了避免链接错误,你应该在onCreate()方法的开头加上”@SuppressLint(”NewApi”)”标签。
此时的DisplayMessageActivity看起来是这个样子的:
public class DisplayMessageActivity extends Activity {
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
// Make sure we're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
如果你用的是非Eclipse集成开发环境,拷贝上面的代码到DisplayMessageActivity类中。
所有Activity的子类都必须实现onCreate()方法,当创建一个新的窗口实例时,系统会首先调用它,它是你应该通过setContentView()方法设置窗口布局和初始化窗口各组件的地方。
添加一个字符串资源
如果你用的是Eclipse,你可以直接跳到下一步,因为模板中已经提供了这个字符串。
相反,你需要在strings.xml文件中添加如下属性值:
<resources>
...
<string name="title_activity_display_message">My Message</string>
</resources>
将该类在Mainfest中注册
所有窗口都应该在AndroidManifest.xml文件中通过<activity>标签定义。
当你用Eclipse工具创建窗口时,它将会创建默认入口,如果你用的是其它集成开发环境,你需要在manifest入口文件中自己加入activity标签属性值,如下所示:
<application ... >
...
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>
“android:parentActivityName”是定义窗口在逻辑上的父窗口,系统通过这个属性值来实现默认导航,比如在Android 4.1及以上版本中的”Up navigation”。
如果你用的是Eclipse,你现在就可以运行程序并能够看到我们想要的效果,但是此时跳转到的窗口只有一个默认的”Hello World”,接下来就是更新第二个窗口的布局啦。
接收Intent信息
每一个窗口都可以通过”getIntent()”方法来获取传递过来的数据信息。
在DisplayMessageActivity类的onCreate()方法中,通过如下代码获取数据:
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
显示信息
为了能够在屏幕上显示信息,在类中创建一个TextView实例并通过setText方法来设置组件的值,然后将TextView作为窗口的根布局通过setContentView()添加到窗口中。
完整的onCreate()方法是这样的:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the message from the intent
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
// Set the text view as the activity layout
setContentView(textView);
}
到现在为止你可以运行这个程序啦,在主界面的编辑框中输入文本,点击发送按钮,你将会在跳转到的窗口中看到刚才输入的文本信息。
好啦,你已经完整地创建了你的第一个应用啦。
要想学得更多,还得接着看后面的课程啊。