对于许多刚开始Android学习的朋友来说,Activity是一个比较难理解的概念。但是任何一个APPS都是由最重要的Activity开始的。
首先,简单说一下Android中的基本组件: Intent and Intent Filters、Activities、Services、Content Providers、App Widgets、Processes and Threads来源于Android API。其中Activity是很重要的。
1. Activity简介
Activity 是这样一个程序组件,它为用户提供一个用于任务交互的画面。例如,拨打电话,拍照,发邮件。或者查看地图。每一个activity都被分配一个窗口。在这个窗口里,你可以绘制用户交互的内容。 这个窗口通常占满屏幕,但也有可能比屏幕小,并且浮在其它窗口的上面。
一个应用程序通常由多个activity组成,它们彼此保持弱的绑定状态。典型的,当一个activity在一个应用程序内被指定为主activity, 那么当程序第一次启动时,它将第一个展现在用户面前。为了展现不同的内容,每一个activity可以启动另外一个。 每当一个新的activity被启动,那么之前的将被停止。但系统将会把它压入一个栈(“back stack”即后退栈),当一个新的activity启动,它将被 放到栈顶并获得用户焦点。后台栈遵循后进先出的栈机制。所以当用户完成当前页面并按下返回按钮时,它将被pop出栈(并销毁),之前的activity将被恢复。
当一个activity因为另一个activity的启动而被停止,那么其生命周期中的回调方法,将会以状态改变的形式被调用。 activity通过它自身状态的改变可以收到多个回调方法。当系统创建,停止,恢复,销毁它的时候。并且每个回调方法都给你做相应处理工作的机会。 例如,当停止的时候,你的activity应当释放比较大的对象,例如网络连接,数据连接。当你的activity恢复时,你可以请求必须的资源并恢复一些被打断的动作。 这些状态事务的处理就构成了activity的生命周期。
2.Activity的生命周期
在【1】中提到【回退栈】、Activity的【创建】、【停止】、【恢复】、【销毁】等,这就涉及到Activity生命周期的相关信息了。
仔细看这张图,Activity的生命周期可以总结为一下几个状态:
- 启动Activity
- 当前Activity被其他Activity覆盖或锁屏
- Activity被关闭(不可再现)
- Activity回到前台(解锁屏或返回该Activity)
- 其他应用需要内存
系统在不同的状态之间切换时,回调不同的方法:
- onCreate()
- activity第一次被创建时调用。在这里你应该完成所有常见的静态设置工作——创建view、绑定list数据等等。 本方法传入一个包含了该activity前一个状态的Bundle对象(如果之前已捕获了状态的话,详见后面的保存Activity状态)。下一个回调方法总是onStart()。
- onRestart()
- activity被停止后、又再次被启动之前调用。下一个回调方法onStart()
- onStart()
- activity要显示给用户之前调用。如果activity进入前台,则下一个回调方法是onResume();如果进入隐藏状态,则下一个回调方法onStop()。
- onResume()
- activity开始与用户交互之前调用。这时activity是在activity栈的顶端,用户可以向其中输入。下一个回调方法总是onPause()。
- onPause()
- 当系统准备启动另一个正在恢复的activity时调用。这个方法通常用于把未保存的改动提交为永久数据、停止动画播放、以及其它可能消耗CPU的工作等等。 它应该非常迅速地完成工作,因为下一个activity在本方法返回前是不会被恢复运行的。
如果activity返回前台,则下一个回调方法是onResume();如果进入用户不可见状态,则下一个是onStop()
- onStop()
- 当activity不再对用户可见时调用。原因可能是它即将被销毁、或者其它activity(已有或新建的)被恢复运行并要覆盖本activity。
如果activity还会回来与用户交互,则下一个回调方法是onRestart();如果这个activity即将消失,则下一个回调方法是onDestroy()
- onDestroy()
- 在本activity被销毁前调用。这是activity收到的最后一个调用。
可能是因为activity完成了工作(有些人在这里调用finish()),
也可能是因为系统为了腾出空间而临时销毁activity的本实例。 可以利用isFinishing() 方法来区分这两种情况。
经过上面的介绍,我们发现不同的回调方法具有不同的功能,除了系统定义的功能外,我们还需要定义应用需要的一些事情,这里可以创建一个Activity来说明。
3.创建一个Activity
Activity 是继承于Activity的java类
MainActivity.java如下
package com.hhu.lilj; //包名
import android.app.Activity;
import android.os.Bundle;//引入Activity包、Bundle包
import android.view.Window;
public class MianActivity extends Activity {
/**
首先回调onCreate()方法,设置Activity的UI,去掉主题中的标题栏
**/
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
setContentView(R.layout.main);//设置Activity的界面
}
}
main.xml如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是第一个Activity"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
AndroidManifest.xml修改如下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.veranoteaccount"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name="com.hhu.lilj.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
插入的代码如下:注册一个Activity,并设置为启动界面
<activity
android:name="com.hhu.lilj.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
设置为启动界面:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
一个Activity创建好了,这对于Android初学者来说只是简单的一小步。
在创建Activity时我们发现使用了Bundle这一组件,最后介绍一下Bundle组件
4.Bundle组件
Bundle在
ava.lang.Object
↳ android.os.Bundle
**类中。它是一个key-value对(A mapping from String values to various Parcelable types. )
onCreate()方法中的Bundle是一个静态全局变量,是一个Map类型的变量。**
Bundle可以用于Activity之间值传递
第一个Activity
1.新建一个Bundle
Bundle bundle = new Bundle();
2.设置bundle的”key”和“value”
bundle.putString("message", messgeString);
3.新建一个Intent对象,并将新建的Bundle传给它
Intent intent = new Intent();
intent.setClass(MianActivity.this, SecondActivity.class);
intent.putExtras(bundle);
startActivity(intent);
第二个Activity
新建Bundle用来获取Intent中的Bundle,并用”key”取得其中的“value”
Bundle bundle = getIntent().getExtras();
String messageString = bundle.getString("message");
textView.setText(messageString);
完整代码如下:
MianAvtivity
package com.hhu.lilj; //包名
import com.example.veranoteaccount.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;//引入Activity包、Bundle包
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MianActivity extends Activity {
private TextView textView;
private Button button;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
setContentView(R.layout.main);//设置Activity的界面
textView = (TextView)this.findViewById(R.id.button);
button = (Button)this.findViewById(R.id.editText);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String messgeString = textView.getText().toString().trim();
if (messgeString.equals("")) {
Toast.makeText(getApplicationContext(), "请输入要传递的值", 1);
}else {
Bundle bundle = new Bundle();
bundle.putString("message", messgeString);
Intent intent = new Intent();
intent.setClass(MianActivity.this, SecondActivity.class);
intent.putExtras(bundle);
startActivity(intent);
}
}
});
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="输入要传递的值"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转至第二个Activity" />
</LinearLayout>
SecondActivity
package com.hhu.lilj;
import com.example.veranoteaccount.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class SecondActivity extends Activity{
private TextView textView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sactivity);
textView = (TextView)this.findViewById(R.id.textView);
Bundle bundle = getIntent().getExtras();
String messageString = bundle.getString("message");
textView.setText(messageString);
}
}
sactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="从第一个Activity传来的值"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>