Android 系统由Activity、Service、Broadcast Receiver、Content Provider组成。其中,Activity是使用频率最高、最重要的组件。在Android系统中Activity提供可视化的用户界面,一个Android应用通常由多个Activity组成。多个Activity组成了Activity栈(Stack),当前活动的Activity处于栈顶。Activity有自己的生命周期,由Android系统来控制。
在Activity的上面是一个Window对象,在Window之上通常是一个布局容器对象(如一个LinearLayout),再上面是我们要展示的组件,如按钮、文本框等。
一、何谓回调?
下面通过实例来模拟一下Android中Activity的方法回调思想
/**
* Activity接口(为了说明问题这里只定义了三个方法)
*/
public interface Activity {
public void onCreate();//创建时调用的方法
public void onStart();//启动时调用的方法
public void onDestroy();//销毁时调用的方法
}
/**
* Activity的实现类MyActivity
*/
public class MyActivity implements Activity {
@Override
public void onCreate() {
System.out.println("onCreate()...");
}
@Override
public void onStart() {
System.out.println("onStart()...");
}
@Override
public void onDestroy() {
System.out.println("onDestroy()...");
}
}
/**
* 系统运行环境AndroidSystem
*/
public class AndroidSystem {
//定义创建常量
public static final int CREATE = 1;
//定义启动常量
public static final int START = 2;
//定义销毁常量
public static final int DESTROY = 3;
//运行方法
public void run(Activity a,int state){
switch(state){
case CREATE:
a.onCreate();
break;
case START:
a.onStart();
break;
case DESTROY:
a.onDestroy();
break;
}
}
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
//实例化AndroidSystem
AndroidSystem system = new AndroidSystem();
//实例化MyActivity
Activity a = new MyActivity();
system.run(a, AndroidSystem.CREATE);
system.run(a, AndroidSystem.START);
system.run(a, AndroidSystem.DESTROY);
}
}
通过上述代码可以看出,接口(系统框架)是系统提供的,接口的实现是用户实现的。这样可以达到接口统一,实现不同。
系统通过在不通的状态“回调”我们的实现类,来达到接口和实现的分类。
二、Activity简介
1 、Activity的创建
Activity提供了和用户交互的可视化界面。创建一个Activity一般是继承Activity(或ListActivity、MapActivity等),覆盖Activity的onCreate()方法,在该方法中调用setContextView()方法展示要显示的视图,调用findviewById()方法实例化组件。注意Activity只有在清单文件中声明才能使用。
public class TestActivity01 extends Activity {
private TextView myTextView;
private Button myButton;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myTextView = (TextView) findViewById(R.id.TextView01);
myButton = (Button) findViewById(R.id.Button01);
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="简单的Activity" />
<Button
android:id="@+id/Button01"
android:text="I'm Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
2、启动另一个Activity
从一个Activity启动另一个Activity,可以使用startActivity()方法或者startActivityForResult()方法(能够返回结果)。这两个方法传递的参数是Android中的另一个非常重要的组件(Intent),Intent是相同或不同组件的信使。
下面演示一个实例,有两个Activity:FirstActivity和SecondActivity。每个Activity都有一个按钮,F中的按钮响应事件跳转到S,S中的按钮响应事件跳转到F。
public class FirstActivity extends Activity{
private Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first);
button1 = (Button) findViewById(R.id.firstActivityButton01);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
}
public class SecondActivity extends Activity {
private Button button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
button2 = (Button) findViewById(R.id.secondActivityButton01);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this,FirstActivity.class);
startActivity(intent);
}
});
}
}
first.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/firstActivityButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second Activity" />
</LinearLayout>
second.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/secondActivityButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Return" />
</LinearLayout>
3、Activity之间传递数据
通过Bundle传递数据,将要传递的信息封装到该对象里面,并通过Intent对象传递到另一个Intent中。
在Android系统中提供了一个联系人管理应用程序,本实例是在这个应用程序基础上实现的,在这个实例的第一个Activity中,要求用户输入用户名称,通过用户名称查询用户联系方式并在第二个Activity中显示,这里需要将用户名称传递给第二个Activity。
public class PassDataActivity extends Activity {
private EditText myEditText;
private Button myButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.passdata);
myEditText = (EditText) findViewById(R.id.passDataEditText01);
myButton = (Button) findViewById(R.id.passDataButton01);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
String name = myEditText.getText().toString();
Bundle data = new Bundle();
data.putString("name", name);
Intent intent = new Intent(PassDataActivity.this,PassDataResultActivity.class);
//为Intent添加Bundle
intent.putExtras(data);
startActivity(intent);
}
});
}
}
public class PassDataResultActivity extends Activity {
private TextView myTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.passdataresult);
myTextView = (TextView) findViewById(R.id.passResultTextView01);
Intent intent = getIntent();
Bundle b = intent.getExtras();
String name = b.getString("name");
String[] projection = new String[]{People._ID,People.NAME,People.NUMBER};
Uri contacts = People.CONTENT_URI;
String[] args = {name};
Cursor managerCursor = managedQuery(contacts, projection, "name=?", args, People.NAME + "ASC");
if(managerCursor.moveToFirst()){
String name1 = managerCursor.getString(1);
String number = managerCursor.getString(2);
myTextView.setText(name1 + ":" + number);
}
}
}
passdata.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/passDataTextView01"
android:text="请输入用户名:"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/passDataEditText01"
android:text=""
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/passDataButton01"
android:text="查询"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right" />
</LinearLayout>
passdataresult.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/passResultTextView01"
android:text=""
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
4、启动另一个Activity并返回结果
使用另外一个方法startActivityForResult()。例如,在注册一个系统会员的时候经常需要多个步骤,我们经常使用“上一步”、“下一步”来完成,那么当用户在返回“上一步”时该如何保存信息呢?
public class OneActivity extends Activity {
private EditText username,password;
private Button b;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
username = (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
b = (Button) findViewById(R.id.oneButton);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
String uname = username.getText().toString();
String pwd = password.getText().toString();
Bundle data = new Bundle();
//为Bundle添加用户名和密码
data.putString("name", uname);
data.putString("pwd", pwd);
Intent intent = new Intent(OneActivity.this,TwoActivity.class);
intent.putExtras(data);
startActivityForResult(intent, 0);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//从Intent中取出Buundle
Bundle b = data.getExtras();
String name = b.getString("name");
String pwd = b.getString("pwd");
username.setText(name);
password.setText(pwd);
}
}
public class TwoActivity extends Activity {
private Button b;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.next);
b = (Button) findViewById(R.id.twoButton);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = getIntent();
//设置返回结果
TwoActivity.this.setResult(0, intent);
//结束当前Activity
TwoActivity.this.finish();
}
});
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/oneTextView01"
android:text="用户名称:"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/username"
android:text=""
android:layout_width="fill_parent"
android:layout_height="wrap_conent" />
<TextView
android:id="@+id/oneTextView02"
android:text="用户密码:"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/password"
android:text=""
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/oneButton"
android:text="Next"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
next.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/twoTextVeiw01"
android:text="Email:"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/email"
android:text=""
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/twoTextView02"
android:text="Mobile:"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/mobile"
android:text=""
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/twoButton"
android:text="Pre"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
三、Activity的生命周期
在Android系统中Activity作为Activity栈被管理,当前活动的Activity处于栈顶,之前的非活动Activity被压入下面成为非活动Activity,等待是否可能被恢复为活动状态。
在Activity的生命周期中有四个重要的状态:
状态 | 状态描述 |
活动 | 在屏幕的前面(在栈顶),有焦点并可见 |
暂停 | 失去了焦点,但是它仍然可见 |
停止 | 失去焦点,不可见 |
销毁 | 被系统或进程结束 |
【Activity开始】 ——> onCrate() ——> onStart() ——> onResume() ——> 【Activity运行、另一个Activity启动】 ——> onPause() ——> onStop() ——> onDestory()
我们将Activity的生命周期分为以下三个过程:
- 整个完整生命周期:从onCreate()方法开始到onDestory()方法结束。
- 可见生命周期:从onStart()方法开始到onStop()仿佛结束。
- 前台可见生命周期:从onResume()方法开始到onPause()方法结束。
下面通过一个实例来测试一下Activity的生命周期中各个方法的调用情况,在这里我们把Activity的所有方法覆盖,并通过日志的方式来观察运行结果。我们在界面放置一个按钮,当单击按钮时结束Activity,并观察日志输出。
public class MainActivity extends Activity {
private Button btn;
//定义日志标签
private static final String TAG = "liftcycle";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one);
//输出日志
Log.i(TAG, "onCreate......");
btn = (Button) findViewById(R.id.Button01);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
//结束当前Activity
MainActivity.this.finish();
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart......");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart......");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume......");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause......");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop......");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy......");
}
}