一个Android应用一般由4个部分组成:
1. Activity(活动)
2.Intent Receivers(活动接收器)
3. Service(服务)
4.Content Providers(内容提供器)
在本文中,我们将具体研究一下Activity。Activitie代表了Android应用的屏幕显示。 Android平台定义了‘Activity’类, 所有其他的Activity都要继承这个父类。
Android平台被设计成所有应用都可以使用以上4个组成部分来暴露接口,以进行相互交互。而使用XML进行界面定义是一种中非常必要的开发手段(开发无边界的应用)
在 XML中定义用户界面:
Activity中可以包含一系列的View和ViewGroup。View是标准的屏幕组件,如:TextView (文本标签), Buttons, CheckBox, EditText (文本输入框)等等。ViewGroup是一种可以包含其他View的特殊View,因此ViewGroup可以作为面板来使用。像LinearLayout, RelativeLayout, AbsoluteLayout等都是一种ViewGroup。
Android支持使用XML语法来设计屏幕界面。让我们来基于XML设计一个可以输入用户的姓和名的用户界面:
xml version =”1.0″ encoding =”utf-8″ ?>
< LinearLayout
android:id =”@+id/widget28″
android:layout_width =”fill_parent”
android:layout_height =”fill_parent”
android:orientation =”vertical”
xmlns:android =”” >
< TextView
android:id =”@+id/firstNameLabel”
android:layout_width =”wrap_content”
android:layout_height =”wrap_content”
android:text =”First Name:” >
TextView >
< EditText
android:id =”@+id/firstName”
android:layout_width =”319px”
android:layout_height =”wrap_content”
android:textSize =”18sp” >
EditText >
< TextView
android:id =”@+id/lastNameLabel”
android:layout_width =”wrap_content”
android:layout_height =”wrap_content”
android:text =”Last Name:” >
TextView >
< EditText
android:id =”@+id/lastName”
android:layout_width =”320px”
android:layout_height =”wrap_content”
android:textSize =”18sp” >
EditText >
< Button
android:id =”@+id/submitButton”
android:layout_width =”wrap_content”
android:layout_height =”wrap_content”
android:text =”Submit”
android:layout_gravity =”center_horizontal” >
Button >
LinearLayout >
这里有一个可视化的Android XML界面设计工具,可以尝试一下: 。
以上Activity布局显示了两个文本输入框,分别用来输入用户的姓和名,每个界面控件都设置了一个id来进行区分,这个id也可以用来对控件进行访问。Activity布局文件被存放在工程的res/layout目录下。
Activity Intent:
每个Activity都和一系列的Intent关联,这些Intent用来指示Activity可以做什么事。Intent包含了执行Activity所需要的数据和动作。 所有的Intent都在AndroidManifest.xml文件中定义成Intent过滤器。 Activity支持多动作。参看下面的例子:
< activity class =”.SomeActivity” android:label =”@string/activityTitle” >
< intent-filter >
< action android:value =”android.intent.action.VIEW” />
< category android:value =”android.intent.category.DEFAULT” />
< type android:value =”content://contacts” />
intent-filter >
activity >
上面这个Activity支持View对系统中联系人列表的数据进行访问,也就是说它可以显示手机中的所有联系人名单中的信息。Intent中有一组预定义的动作,如:VIEW,EDIT,MAIN等等;自定义的动作可以这样来进行定义:
< activity class =”.TestActivity” android:label =”@string/activityTitle” >
< intent-filter >
< action android:value =”com.wissen.testApp.activities.TEST_ACTIVITY” />
< category android:value =”android.intent.category.DEFAULT” />
intent-filter >
activity >
这个Activity将会在使用TEST_ACTIVITY这个Intent时被激活。在下面的文章中,我们将学习如何创建Activity和Intent。
应用程序启动器Activity(即应用程序运行时默认执行的Activity):
每一个Android应用程序都有一个启动器Activity。启动器Activity是一个应用程序开始执行时就自动运行的Activity。
启动器Activity需要支持预定义的 ‘android.intent.action.MAIN’ 这一Intent,以及需要具备 ‘android.intent.category.LAUNCHER’这个运行目录。
启动器Activity可以在AndroidManifest.xml进行如下定义:
< activity class =”.WelcomeActivity” android:label =”@string/app_name” >
< intent-filter >
< action android:value =”android.intent.action.MAIN” />
< category android:value =”android.intent.category.LAUNCHER” />
intent-filter >
activity >
创建Activity:
我们所有要创建的Activity必须继承 ‘Activity’这个基础类。当系统创建一个Activity的实例时,这个类的 onCreate()方法就会被调用。
我们来看下列的示例代码:
package com.wissen.testApp;
public class UserInfoActivity extends Activity {
private EditText firstName;
private EditText lastName;
@Override
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.main);
firstName = (EditText) findViewById(R.id.firstName);
lastName = (EditText) findViewById(R.id.lastName);
submitButton = (Button) findViewById(R.id.saveButton);
}
} package com.wissen.testApp;
public class UserInfoActivity extends Activity {
private EditText firstName;
private EditText lastName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
firstName = (EditText) findViewById(R.id.firstName);
lastName = (EditText) findViewById(R.id.lastName);
submitButton = (Button) findViewById(R.id.saveButton);
}
}
以上的这个Activity类覆盖了父类的 onCreate方法。onCreate方法是Activity生命周期管理方法中的其中一个方法,正如其名,它将会在创建这个Activity实例的时候被调用,因此,其实这个onCreate方法就是进入一个Activity的入口。
Activity类中会调用 setContentView方法来设置由xml定义的界面布局。代码中的R这个类是一个Android应用程序的资源类,存储了所有可以引用的资源,在这里R.layout.main表示引用main.xml这个布局文件。
如我们所看到的,在前面的xml布局文件中,所有的控件都设置了一个id,从而使得Activity可以通过这个id来访问到它们(使用findViewById方法)。
到这里为止,我们已经让我们的XML布局方式生效了,在代码中我们现在可以访问到firstName,lastName和saveButton这几个控件了。
接下来,我们来为界面上的这个提交按钮添加一个onClick事件处理器,我们让用户输入的firstName和lastName以通知消息框的形式显示出来。
public class UserInfoActivity extends Activity implements View.OnClickListener {
private EditText firstName;
private EditText lastName;
@Override
public void onCreate(Bundle savedInstanceState) {
…
}
public void onClick(View view) {
if (view.getId() == R.id.submitButton) {
Toast.makeText(context, “Hi ” + firstName.getText() + ” ” + lastName.getText().toString(), Toast.LENGTH_LONG).show();
}
}
} public class UserInfoActivity extends Activity implements View.OnClickListener {
private EditText firstName;
private EditText lastName;
@Override
public void onCreate(Bundle savedInstanceState) {
…
}
public void onClick(View view) {
if(view.getId() == R.id.submitButton) {
Toast.makeText(context, “Hi ” + firstName.getText() + ” ” + lastName.getText().toString(), Toast.LENGTH_LONG).show();
}
}
}
将这个Activity在AndroidManifest.xml配置成启动器Activity,则整个应用程序启动的时候就会开始调用这个Activity。
Activity的生命周期:
让我们来看下Activity的生命周期是怎么样的, Activity类支持以下几个生命周期相关的方法:
onCreate(): 当Activity第一次被创建的时候调用。
onRestart(): 当Activity从停止运行的状态到开始运行的状态的时候被调用。
onStart(): 当Activity展示给用户看到的时候被调用。如果本Activity处于Activity栈的顶部,则onStart方法紧随着onResume方法的调用而调用。
onResume(): 当Activity开始将与用户进行交互时被调用。
onPause(): 当其他Activity被激活时,当前Activity的onPause将被调用。
onStop(): 当前Activity不再对用户可见的时候被调用(即可能是一个新的Activity被激活,或者是当前的Activity被销毁)
onDestroy(): 当前Activity被销毁之前被调用。要销毁一个Activity,可以调用finish()方法。
启动一个Activity:
由前面我们已经知道了怎样去创建和显示一个启动器Activity,我们现在来看下如何去运行和展示其他的Activity。
假设你已经定义好了如下的一个Activity:
package com.wissen.testApp;
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
…
}
} package com.wissen.testApp;
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
…
}
}
在AndroidManifest.xml中进行配置:
< activity class =”.TestActivity” android:label =”@string/activityTitle” >
< intent-filter >
< action android:value =”com.wissen.testApp.activities.TEST_ACTIVITY” />
< category android:value =”android.intent.category.DEFAULT” />
intent-filter >
activity >
要将这个Activity展示给用户的话,则它必须被运行。我们可以这样来运行它:
Intent testActivityIntent = new Intent();
testActivityIntent.setAction(”com.wissen.testApp.activities.TEST_ACTIVITY”);
startActivity(myProfileIntent); Intent testActivityIntent = new Intent();
testActivityIntent.setAction(”com.wissen.testApp.activities.TEST_ACTIVITY”);
startActivity(myProfileIntent);
我们也可以直接在Intent中设置要运行的Activity的类名来实现,如:
intent.setClass(context, TestActivity. class ); intent.setClass(context, TestActivity.class);
有时候主调Activity需要得到一些只有在被调Activity中才能得到的值,这种情况下,我们可以借助 startActivityForResult() 方法来实现,参见以下例子:
public class MyActivity extends Activity {
…
static final int REQUEST_CODE = 0 ;
protected boolean onKeyDown( int keyCode, KeyEvent event) {
startActivityForResult( new Intent(”activity.Action”), REQUEST_CODE);
return true ;
}
protected void onActivityResult( int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (resultCode == RESULT_OK) {
.. do something with the result
}
}
}
} public class MyActivity extends Activity {
…
static final int REQUEST_CODE = 0;
protected boolean onKeyDown(int keyCode, KeyEvent event) {
startActivityForResult(new Intent(”activity.Action”), REQUEST_CODE);
return true;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (resultCode == RESULT_OK) {
.. do something with the result
}
}
}
}
以上就是一些关于Activity的内容。在接下来的文章中,我们将陆续介绍其他Android平台的其他组成部分。