Android 四大组件之Activity
1.Activity简介:
Activity是Android应用最重要和最常见的组件之一。它提供一个屏幕,用户可以与之交互为了完成某项任务,例如,拨号、拍照等。每一个activity都对应一个窗口,在上面可以绘制用户接口。窗口通常充满屏幕,但也可以小于屏幕而浮于其它窗口之上。(可以看下API文档)
2.Activity的使用
2.1 创建Activity
继承Activity类,重写onCreate()方法。
setContentView(int layoutResID);是给Activity添加View控件,View才是我们实实在在看到的界面。
1 package com.example.administrator.demoactivity; 2 3 import android.os.Bundle; 4 import android.support.v7.app.ActionBarActivity; 5 6 public class MainActivity extends Activity { 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11 } 12 }
2.2 配置Activity
在AndroidManifest.xml中配置Activity
1 <activity 2 android:name=".MainActivity" 3 android:label="@string/app_name" > 4 <intent-filter> 5 <action android:name="android.intent.action.MAIN" /> 6 <category android:name="android.intent.category.LAUNCHER" /> 7 </intent-filter> 8 </activity>
2.3 启动和关闭Activity
一个Android应用通常都包含多个Activity,但只有一个Activity作为程序的入口,当该Android应用启动时他会自动启动并执行该Activity,至于其它Activity由入口Activity启动或由入口Activity启动的Activity启动
Activity启动其它Activity通常有两种方式:
(1).startActivity(Intent intent):启动其它Activity
(2).startActivityForResult(Intent intent,int requestCode):以指定的请求码启动Activity,通过重写onActivityResult()方法来获取新启动的Activity返回的结果
requestCode代表了启动Activity的请求码,该请求码由开发者自行指定,主要是用于标识请求的来源。被启动的Activity需要调用setResult(int resultCode,Intent intent);resultCode是结果标识,intent携带返回的值
intent是Android组件之间进行通讯非常重要的方式,一个Activity通过指定intent来表达自己的"意图"。
Android为关闭Activity提供了以下两种方法:
(1).finish():结束当前Activity
(2).finishActivity(int requestCode):根据requestCode结束以startActivityForResult(Intent intent,int requestCode)启动的Activity
下面写一个例子,使用startActivity(Intent intent,int requestCode);方法启动获取OtherActivity返回的数据
第一个Activity:MainActivity和layout布局
1 package com.example.administrator.demoactivity; 2 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.support.v7.app.ActionBarActivity; 6 import android.widget.TextView; 7 8 public class MainActivity extends ActionBarActivity { 9 //标识请求来源 10 private static final int FLAG_GET_MESSAGE = 1; 11 private TextView textView; 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 17 textView = (TextView) findViewById(R.id.textView); 18 Intent intent = new Intent(this,OtherActivity.class); 19 startActivityForResult(intent,FLAG_GET_MESSAGE); 20 } 21 22 @Override 23 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 24 // super.onActivityResult(requestCode, resultCode, data); 25 if(requestCode == FLAG_GET_MESSAGE && resultCode == OtherActivity.FLAG_BACK_MESSAGE){ 26 if(data != null){ 27 String msg = data.getStringExtra("msg"); 28 textView.setText("从OtherActivity中获取到的信息:"+msg); 29 } 30 } 31 } 32 }
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 3 android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" 4 android:paddingRight="@dimen/activity_horizontal_margin" 5 android:paddingTop="@dimen/activity_vertical_margin" 6 android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> 7 8 <TextView 9 android:id="@+id/textView" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" /> 12 13 </RelativeLayout>
第二个Activity:OtherActivity和layout布局
1 package com.example.administrator.demoactivity; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 7 /** 8 * Created by Administrator on 2015/2/21. 9 */ 10 public class OtherActivity extends Activity{ 11 public static final int FLAG_BACK_MESSAGE = 1; 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_other); 17 18 initData(); 19 } 20 21 public void initData() { 22 Intent intent = new Intent(); 23 intent.putExtra("msg","OtherActivity"); 24 OtherActivity.this.setResult(FLAG_BACK_MESSAGE,intent);//必须设置返回标识 25 OtherActivity.this.finish();//结束当前Activity 26 } 27 28 29 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 </LinearLayout>
结果显示:
2.4 使用Bundle在Activity之间交换数据
Intent提供多个重载的方法来携带额外的数据:
(1).putExtras(Bundle data):
(2).Bundle getExtras();
(3).putExtra(String key,Xxx value); //向intent中以key-value的形式添加数据,其实这种方式本质上也是putExtras(Bundle data),查看源码可知,在Bundle为null是首先会常见一个Bundle然后将数据存到bundle中。下面是Intent类的部分源码:
1 public Intent putExtra(String name, String value) { 2 if (mExtras == null) { 3 mExtras = new Bundle(); 4 } 5 mExtras.putString(name, value); 6 return this; 7 }
(4).getXxxExtra(String name):通过key去除指定的数据
Bundle就是一个简单的数据携带包,查看源码可以发现其包含多个方法来存入数据
putXxx(String key,Xxx data):向Bundle中放入int、Long等类型的数据
putSerializable(String key,Serializable value);向Bundle中添加一个可序列化的对象。
3.Activity的生命周期和加载模式
3.1 Activity的生命周期演示
下面是Android官方提供的Activity生命周期
onCreate():第一次创建Activity时被回调,该方法只会被调用一次
onStart():启动Activity时被回调
onRestart():从新启动Activity时被回调
onResume():用户可以获得焦点时被回调
onPause():当启动其它Activity时被回调,暂停本Activity
onStop():当启动一个Activity后本Activity处于不可见状态,这时被回调
onDestory():销毁Activity时被回调
当用户按back键时,如果前一个Activity不可见,Android系统则回调用onRestart()-->onStart()...
当用户按back键时,如果前一个Activity可见,Android系统则回调onResume()方法;
从上图可以看出当系统内存不够时,系统会kill掉处于onPause()和onStop()状态的Activity
3.2 Activity的4种加载模式
可在配置Activity时指定android:launchMode属性,该属性用于配置Activity的加载模式,支持4中属性
*standard:标准模式,默认加载模式
*singleTop:Task顶单例模式
*singleTask:Task内单例模式
*singleInstance:全局单单例模式
为什么要为Activity指定加载模式?
首先介绍下Android对Activity的管理:Android采用Task来管理多个Activity,当我们启动一个Activity时,系统就会创建一个Task,然后启动这个Activity的入口。
Android并未给Task提供API,只能通过调用Activity的getTaskId()方法获取它所在的Task的ID,我们可以把Task理解为Activity 栈,Task以栈来管理Activity。
下面详细接受Activity的4中加载模式:
*standard加载模式:
每次通过这种模式启动Activity时,Android总会为启动的Activity创建一个新的实例,并将该Activity添加到当前Task栈中,这种模式不会创建新的Task,只是将新
Activity添加到原有的Task 中
*singleTop模式
这种模式类似与standard模式,不同之处在于:当启动的Activity已经位于Task栈的顶部,那么Android不会在在创建Activity实例,而是复用已存在的Activity。
*singleTask模式
被启动的Activity在同一个Task内只有一个Activity实例,具体分为如下三种情况:
<1>.如果启动的目标Activity不存在Task栈中,系统将会创建一个目标Activity实例,并将它加入到Task栈顶
<2>.如果启动的目标Activity已存在Task栈顶,此时模式和singleTop模式相同
<3>.若果启动的目标Activity已存在但没有位于Task栈顶,系统将会把该目标Activity上面的所有Activity移除Task栈,使该Activity置于Task栈顶
*singleInstance模式
这种加载模式下,无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的Task栈来装载该Activity实例。具体可分为两种情况:
<1>.如果创建的目标Activity不存在,系统先会创建一个全新的Task,接着创建一个Activity实例,然后将该目标Activity加入到新的Task栈顶
<2>.如果创建的目标Activity已经存在,无论在哪个Task栈中,系统将会把Activity所在的栈置于前台。
注意:采用singleInstance加载模式的Activity总是位于Task栈顶,并且Activity所在的Task栈只包含该Activity