Activity是android应用的重要组成单元之一(另外3个是Service,BroadcastReceiver和ContentProvider)。实际应用包含了多个Activity,不同的Activity向用户呈现不同的操作界面。Android应用的多个Activity组成Activity栈,当前活动的Activity位于栈顶。对于Android应用而言,Activity主要负责与用户交互,并向用户呈现应用状态。

1 建立、配置和使用Activity

1.1 Activity类简介

  • 当一个Activity定义出来后,该Activity类何时被实例化、它所包含的方法何时被调用,这些都不是由开发者来决定,而是Android系统决定
  • 创建Activity需要重写一个或者多个方法。其中最常见的就是onCreate方法
  • Activity相关类关系视图

  

  • AccountAuthenticatorActivity:实现账户管理界面的Activity
  • TabActivity实现Tab界面的Activity
  • ListActivity实现列表界面的Activity
  • AliasActivity:别名Activity的基类,启动其他Activity时结束自己
  • ExpandableListActivity实现可扩展列表界面的Activity
  • LauncherActivity:实现Activity列表界面的Activity,当单击列表时,所对应的Activity启动
  • PreferenceActivity:实现程序多参数设置,存储界面的Activity

  对于Activity的具体子类如ListActivity,LauncherActivity,ExpandableActivity等无需实现具体的布局文件,会自动调用默认布局文件。

示例:PreferenceActivity的使用

Activity文件

  1. import android.preference.PreferenceActivity;
  2. import android.preference.PreferenceFragment;
  3. import android.support.v7.app.AppCompatActivity;
  4. import android.os.Bundle;
  5. import android.widget.Button;
  6. import android.widget.Toast;
  7.  
  8. import java.util.List;
  9.  
  10. public class PreferenceActivityTest extends PreferenceActivity {
  11.  
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState) {
  14.  
  15. super.onCreate(savedInstanceState);
  16. if(hasHeaders()){
  17. Button button = new Button(this);
  18. button.setText("设置操作");
  19. setListFooter(button);
  20. }
  21. }
  22.  
  23. public void onBuildHeaders(List<Header> target){
  24. loadHeadersFromResource(R.xml.preference_headers, target);
  25. }
  26.  
  27. public boolean isValidFragment(String fragmentName){
  28. return true;//super.isValidFragment(fragmentName);
  29. //return StockPreferenceFragment.class.getName().equals(fragmentName);
  30. }
  31.  
  32. public static class Prefs1Fragment extends PreferenceFragment{
  33. @Override
  34. public void onCreate(Bundle savedInstanceState){
  35. super.onCreate(savedInstanceState);
  36. addPreferencesFromResource(R.xml.preferences);
  37. }
  38. }
  39.  
  40. public static class Prefs2Fragment extends PreferenceFragment{
  41. public void onCreate(Bundle savedInstanceState){
  42. super.onCreate(savedInstanceState);
  43. addPreferencesFromResource(R.xml.display_prefs);
  44. String website = getArguments().getString("website");
  45. Toast.makeText(getActivity(),"网站域名是:" + website, Toast.LENGTH_SHORT).show();
  46. }
  47. }
  48. }

Preference主页布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <preference-headers
  3. xmlns:android="http://schemas.android.com/apk/res/android">
  4. <!-- 指定启动指定PreferenceFragment的列表项 -->
  5. <header android:fragment=
  6. "com.example.penghuster.exampletest.PreferenceActivityTest$Prefs1Fragment"
  7. android:icon="@drawable/ic_settings_applications"
  8. android:title="程序选项设置"
  9. android:summary="设置应用的相关选项" />
  10. <!-- 指定启动指定PreferenceFragment的列表项 -->
  11. <header android:fragment=
  12. "com.example.penghuster.exampletest.PreferenceActivityTest$Prefs2Fragment"
  13. android:icon="@drawable/ic_settings_display"
  14. android:title="界面选项设置 "
  15. android:summary="设置显示界面的相关选项">
  16. <!-- 使用extra可向Activity传入额外的数据 -->
  17. <extra android:name="website"
  18. android:value="www.crazyit.org" />
  19. </header>
  20. <!-- 使用Intent启动指定Activity的列表项 -->
  21. <header
  22. android:icon="@drawable/ic_settings_display"
  23. android:title="使用Intent"
  24. android:summary="使用Intent启动某个Activity">
  25. <intent android:action="android.intent.action.VIEW"
  26. android:data="http://www.crazyit.org" />
  27. </header>
  28. </preference-headers>

Fragment1布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  3. <!-- 设置系统铃声 -->
  4. <RingtonePreference
  5. android:ringtoneType="all"
  6. android:title="设置铃声"
  7. android:summary="选择铃声(测试RingtonePreference)"
  8. android:showDefault="true"
  9. android:key="ring_key"
  10. android:showSilent="true">
  11. </RingtonePreference>
  12. <PreferenceCategory android:title="个人信息设置组">
  13. <!-- 通过输入框填写用户名 -->
  14. <EditTextPreference
  15. android:key="name"
  16. android:title="填写用户名"
  17. android:summary="填写您的用户名(测试EditTextPreference)"
  18. android:dialogTitle="您所使用的用户名为:" />
  19. <!-- 通过列表框选择性别 -->
  20. <ListPreference
  21. android:key="gender"
  22. android:title="性别"
  23. android:summary="选择您的性别(测试ListPreference)"
  24. android:dialogTitle="ListPreference"
  25. android:entries="@array/gender_name_list"
  26. android:entryValues="@array/gender_value_list" />
  27. </PreferenceCategory>
  28. <PreferenceCategory android:title="系统功能设置组 ">
  29. <CheckBoxPreference
  30. android:key="autoSave"
  31. android:title="自动保存进度"
  32. android:summaryOn="自动保存: 开启"
  33. android:summaryOff="自动保存: 关闭"
  34. android:defaultValue="true" />
  35. </PreferenceCategory>
  36. </PreferenceScreen>

Fragment2布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  3. <!-- 设置系统铃声 -->
  4. <RingtonePreference
  5. android:ringtoneType="all"
  6. android:title="设置铃声"
  7. android:summary="选择铃声(测试RingtonePreference)"
  8. android:showDefault="true"
  9. android:key="ring_key"
  10. android:showSilent="true">
  11. </RingtonePreference>
  12. <PreferenceCategory android:title="个人信息设置组">
  13. <!-- 通过输入框填写用户名 -->
  14. <EditTextPreference
  15. android:key="name"
  16. android:title="填写用户名"
  17. android:summary="填写您的用户名(测试EditTextPreference)"
  18. android:dialogTitle="您所使用的用户名为:" />
  19. <!-- 通过列表框选择性别 -->
  20. <ListPreference
  21. android:key="gender"
  22. android:title="性别"
  23. android:summary="选择您的性别(测试ListPreference)"
  24. android:dialogTitle="ListPreference"
  25. android:entries="@array/gender_name_list"
  26. android:entryValues="@array/gender_value_list" />
  27. </PreferenceCategory>
  28. <PreferenceCategory android:title="系统功能设置组 ">
  29. <CheckBoxPreference
  30. android:key="autoSave"
  31. android:title="自动保存进度"
  32. android:summaryOn="自动保存: 开启"
  33. android:summaryOff="自动保存: 关闭"
  34. android:defaultValue="true" />
  35. </PreferenceCategory>
  36. </PreferenceScreen>

注意:需要重写PreferenceActivity的isValidFragment方法

1.2 配置Activity

  • Android应用要求多有应用程序组件(Activity、Service、ContentProvider、BroadcastReceiver)都必须显式进行配置
  • 只需为<application/>元素添加<Activity />子元素即可,另外需要为Activity元素指定一个或者多个intent-filter,该元素用于指定该Activity可以响应的Intent
  • 从DDMS查看PreferenceActivity输出的配置文件

1.3 启动关闭Activity

1.3.1 一个Android应用通常会包含多个Activity,但只有一个Activity会作为程序入口-----但Android应用运行时将会自动启动并执行该Activity。其他Activity一般都由入口Activity启动,或者由入口启动的Activity启动,启动Activity的方法有如下两种:

  • startActivity(Intent intent):启动其他Activity
  • startActivityForResult(Intent intent,int requestCode):以指定的请求码(requestCode)启动Activity,而且程序将会等到新启动Activity的结果(通过重写onActivityResult()方法来获取)

1.3.2 Activity关闭有两个方法:

finish(),结束当前Activity

  • finishActivity(int requestCode):结束一startActivityForResult的Activity

1.4 使用Bundle在Activity之间交换数据

  当一个Activity启动另一个Activity时,常常会有一些数据需要传过去,Activity之间的数据交换是通过Intent来完成,Intent提供了多个重载的方法来携带额外的数据,主要接口如下:

操作对象 Intent Bundle
发送

putExtras( Bundle data)  /  putExtras(String name, Xxx value)

putXxx(String key, Xxx data)  /  putSerializable(String key, Serializable data)
接收

Bundle getextras()         / Xxx getXxxExtras(String name)

Xxx getXxx(String key)          /   Serializable getSerializable(String key)

注意:Intent的putExtras方法是智能的,会根据Intent对象内是否存在Bundle对象而自动决定是否需要创建Bundle对象

总结来说,一个有两种方法进行传输数据:

  • 利用Intent + 内置Bundle 传输数据方法

    发送:Intent intent = new Intent(BundleTest.this,ResultActivity.class);   intent.putExtra("person", (Serializable) p);

    接收:Intent intent = getIntent(); Person p = (Person)intent.getSerializableExtra("person");

  • 利用Intent + 自建Bungle 传输数据方法

    发送:Intent intent = new Intent(BundleTest.this,ResultActivity.class);  Bundle data = new Bundle();

data.putSerializable("person", p);    intent.putExtras(data);

    接收:Intent intent = getIntent();    Bundle data = intent.getExtras();    Person p = (Person)data.getSerializable("person");

示例:

发送Activity代码

  1. import org.crazyt.model.Person;
  2.  
  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.widget.Button;
  9. import android.widget.EditText;
  10. import android.widget.RadioButton;
  11.  
  12. import java.io.Serializable;
  13.  
  14. public class BundleTest extends Activity {
  15. @Override
  16. public void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.main);
  19. Button bn = (Button) findViewById(R.id.bn);
  20. bn.setOnClickListener(new OnClickListener() {
  21. public void onClick(View v) {
  22. EditText name = (EditText) findViewById(R.id.name);
  23. EditText passwd = (EditText) findViewById(R.id.passwd);
  24. RadioButton male = (RadioButton) findViewById(R.id.male);
  25. String gender = male.isChecked() ? "男 " : "女";
  26. Person p = new Person(name.getText().toString(), passwd
  27. .getText().toString(), gender);
  28.  
  29. //创建一个Bundle对象
  30. Intent intent = new Intent(BundleTest.this,
  31. ResultActivity.class);
  32.  
  33. //1、利用Intent + 内置Bundle 传输数据方法
  34. // intent.putExtra("person", (Serializable) p);
  35.  
  36. //2 、利用Intent + 自建Bungle 传输数据方法
  37. Bundle data = new Bundle();
  38. data.putSerializable("person", p);
  39. intent.putExtras(data);
  40.  
  41. //启动intent对应的Activity
  42. startActivity(intent);
  43. }
  44. });
  45. }
  46. }

接收Activity代码

  1. import org.crazyt.model.Person;
  2.  
  3. public class ResultActivity extends Activity {
  4. @Override
  5. public void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.result);
  8.  
  9. TextView name = (TextView) findViewById(R.id.name);
  10. TextView passwd = (TextView) findViewById(R.id.passwd);
  11. TextView gender = (TextView) findViewById(R.id.gender);
  12.  
  13. // 获取启动该Result的Inten
  14. Intent intent = getIntent();
  15.  
  16. //直接利用Intent传输数据方法1
  17. // Person p = (Person) intent.getSerializableExtra("person");
  18.  
  19. //直接利用Intent传输数据方法2
  20. Bundle data = intent.getExtras();
  21. Person p = (Person) data.getSerializable("person");
  22.  
  23. name.setText("您的用户名为:" + p.getName());
  24. passwd.setText("您的密码为:" + p.getPass());
  25. gender.setText("您的性别为:" + p.getGender());
  26.  
  27. }
  28. }

效果图

点击注册->

1.5 启动其他Activity并返回结果

  简单地讲,就是当前Activity1启动另一个Activity2,Activity1需要获得Activity2的运行结果;而这也是通过Bundle进行数据交换的,为了获取被启动的Activity所返回的结果,需要从两方面入手:

  • 当前Activity需要重写onActivityResult(int requestCode, int resultCode, Intent intent),当被启动的Activity返回结果时,该方法将会被触发
  • 被启动的Activity需要调用setResult()方法设置处理结果

示例:

启动Activity代码

  1. import android.app.Activity;
  2. import android.content.Intent;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.TextView;
  6.  
  7. import org.crazyt.model.Person;
  8.  
  9. public class ResultActivity extends Activity
  10. {
  11. @Override
  12. public void onCreate(Bundle savedInstanceState)
  13. {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.result);
  16. }
  17.  
  18. public void click(View view){
  19. Intent intent = new Intent(ResultActivity.this,
  20. BundleTest.class);
  21. startActivityForResult(intent,0);
  22. }
  23.  
  24. public void onActivityResult(int requestCode, int resultCode, Intent intent){
  25. if (requestCode == resultCode){
  26. Bundle data = intent.getExtras();
  27. Person result = (Person)data.getSerializable("person");
  28. TextView name = (TextView) findViewById(R.id.name);
  29. TextView passwd = (TextView) findViewById(R.id.passwd);
  30. TextView gender = (TextView) findViewById(R.id.gender);
  31. name.setText("您的用户名为:" + result.getName());
  32. passwd.setText("您的密码为:" + result.getPass());
  33. gender.setText("您的性别为:" + result.getGender());
  34. }
  35. }
  36. }

操作Activity代码

  1. import org.crazyt.model.Person;
  2.  
  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.widget.Button;
  9. import android.widget.EditText;
  10. import android.widget.RadioButton;
  11.  
  12. import java.io.Serializable;
  13.  
  14. public class BundleTest extends Activity {
  15. @Override
  16. public void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.main);
  19. Button bn = (Button) findViewById(R.id.bn);
  20. bn.setOnClickListener(new OnClickListener() {
  21. public void onClick(View v) {
  22. EditText name = (EditText) findViewById(R.id.name);
  23. EditText passwd = (EditText) findViewById(R.id.passwd);
  24. RadioButton male = (RadioButton) findViewById(R.id.male);
  25. String gender = male.isChecked() ? "男 " : "女";
  26. Person p = new Person(name.getText().toString(), passwd
  27. .getText().toString(), gender);
  28.  
  29. Intent intent = getIntent();
  30. Bundle data = new Bundle();
  31. data.putSerializable("person", p);
  32. intent.putExtras(data);
  33. BundleTest.this.setResult(0, intent);
  34. BundleTest.this.finish();
  35. }
  36. });
  37. }
  38. }

效果图

-->-->

2 Acitvity的回调机制

2.1 定义

  所谓回调,对于一个具有通用性质的程序架构来说,程序架构完成整个应用的通用功能、流程,但在某个特定的点上,需要一段业务相关的代码-----而通用程序架构中无法实现这段代码,那么程序架构会在这个点上留一个空。

2.2 对于java程序来说,程序架构在某点上留的空,可以以两种方式存在:

  • 以接口的形式存在,该接口由开发者实现,实现该接口时将会实现该接口的方法,那么通用程序架构就会按需回调该方法完成对应业务
  • 以抽象方法(也可以是非抽象方法)的形式存在,这些特定点的方法已经被定义,开发者可以选择性重写这些方法后,通用程序架构就会按需回调该方法完成对应业务

3 Activity的生命周期

  当Activity处于Android应用中运行时,它的活动状态有android以Activity栈的形式管理,当前活动的Activity位于栈顶。随着不同应用的运行,每个Activity都可能从活动状态转入非活动状态,也可能从非活动状态转入活动状态。

3.1 Activity生命周期的4个状态

  • 活动状态:当前Activity位于前台,用户可见,可以获取焦点
  • 暂停状态:其他Activity位于前台,该Activity仍然可见(处于全透明或非全屏状态),只是不能获取焦点
  • 停止状态:该Activity不可见,失去焦点
  • 销毁状态:该Activity结束,或Activity所在的dalvik进程被结束

3.2 activity生命周期示意图

4 Activity的四种加载模式

4.1 Task管理方法

  • Android采用Task来管理多个Activity,当启动一个应用时,android就会为之创建一个Task,然后启动这个应用的入口Activity
  • Task是以Activity栈的方式来管理Activity的,先启动的放在Task栈底,后启动的放在Task栈顶。
  • Android没有提供Task的API,Task无法访问,只能调用Activity的getTaskId()方法获取当前Activity所在的Task
  • Activity的加载模式就是负责管理和控制Activity实例化、加载方式、以及与Task之间的加载关系

4.2 standard:标准模式,这是默认加载模式

  每次通过standard模式来启动Activity时,Android总会为目标Activity创建一个新的Activity实例,并将该实例添加到当前的Task栈中。

4.3 singleTop:Task顶单例模式

  此模式与standard模式基本类似,唯一不同:当将要被启动的目标Activity已经位于Task栈顶时,系统不会重新创建目标Activity实例,而是直接复用栈顶已有Activity实例

4.4 singleTask:Task内单例模式

  采用singleTask模式的Activity在同一个Task内只有一个实例,当系统采用singleTask模式启动目标Activity时,分为以下三种情况:

  • 如果启动的目标Activity不存在,系统将会创建目标Activity实例,并置于栈顶
  • 如果启动的目标Activity已经位于Task栈顶,则复用该Activity实例,与singleTop模式相同
  • 如果启动的目前Activity已经存在,但不位于Task栈顶,系统将会把位于该Activity上面的所有Activity实例移出Task栈,从而使得目标Activity转入栈顶

  • 4.5 singleInstance:全局单例模式

  采用singleInstance模式,系统保证无论哪个Task中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的Task栈来装载该实例。当系统采用singleInstance模式启动目标Activity时,可以分为以下两种情况:

  • 如果将要启动的目标Activity不存在,系统将会先创建一个全新的Task,在创建目标Activity的实例,并将其加入新的Task的栈顶
  • 如果将要启动的目标Activity已经存在,无论位于哪个应用程序中,无论位于哪个Task中,系统将会把该Activity转到前台,从而使该Activity显示出来
  • 采用该模式加载的Activity总是位于task栈顶,且加载该Activity的Task栈中只有该Activity

Activity详解的更多相关文章

  1. Xamarin android 之Activity详解

    序言: 上篇大概的讲解了新建一个android的流程.今天为大家带来的是Activity详解,因为自己在开发过程中就遇到 好几次坑,尴尬. 生命周期 和Java里头一样一样的,如图 图片来源于网上哈, ...

  2. 详解Android中的四大组件之一:Activity详解

    activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...

  3. [安卓基础] 009.组件Activity详解

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  4. Activity详解生命周期(Android)

    Activity是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器)之 ...

  5. Activity详解四 activity四种加载模式

    先看效果图: 1概述 Activity启动方式有四种,分别是: standard singleTop singleTask singleInstance 可以根据实际的需求为Activity设置对应的 ...

  6. Activity详解三 启动activity并返回结果

    首先看演示: 1 简介 .如果想在Activity中得到新打开Activity 关闭后返回的数据,需要使用系统提供的startActivityForResult(Intent intent, int ...

  7. Activity详解二 activity数据传递

    首先看效果图: 1.Bundle类的作用 Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值.相对于Map,它提供了各种常用类型的putXxx()/getXxx()方 ...

  8. Activity详解一 配置、启动和关闭activity

    先看效果图: Android为我们提供了四种应组件,分别为Activity.Service.Broadcast receivers和Content providers,这些组建也就是我们开发一个And ...

  9. 安卓开发之activity详解(sumzom)

    app中,一个activity通常是指的一个单独的屏幕,相当于网站里面的一个网页,它是对用户可见的,它上面可以显示一些控件,并且可以监听处理用户的时间做出响应. 那么activity之间如何进行通信呢 ...

  10. Android四大组件之Activity详解——传值和获取结果

    废话不多说,先来看效果图 项目源码: http://download.csdn.net/detail/ginodung/8331535 程序说明: 在MainActivity中输入用户名和密码,然后提 ...

随机推荐

  1. Android:使用ViewPager实现左右滑动切换图片(图上有点点)

    在以下实例的基础上加上点点 Android:使用ViewPager实现左右滑动切换图片 (简单版) 效果预览: 因为要把点点放图片上,所以修改布局为相对布局: <?xml version=&qu ...

  2. 186. Reverse Words in a String II

    题目: Given an input string, reverse the string word by word. A word is defined as a sequence of non-s ...

  3. 【安全组网】思科IOS设备基础应用

    思科IOS有2种主要命令行模式:用户模式与特权模式 1.用户模式(user mode),当用“>”表示实在用户模式下 2.特权模式(exec mode),当用"#"表示是在特 ...

  4. 如何保存ISE综合后的RTL schematic为pdf

    如何保存ISE综合后的RTL schematic为pdf 2013-06-23 20:50:10 代码进行综合后,可以得到一个ngr文件,在ISE中打开该文件可以打开RTL schematic,这样每 ...

  5. PHP微信公众平台开发1 配置接口

    1.简介 微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,并实现和特定群体的文字.图片.语音的全方位沟通.互动. 2.通讯机制 3.注册微信公众 ...

  6. Windows Embedded Compact 7新特性

    Windows® Embedded Compact 7是Windows Embedded CE的下一代产品,而Windows Embedded CE这款操作系统面向占用资源少的新颖设备.Windows ...

  7. 【HDOJ】4601 Letter Tree

    挺有意思的一道题,思路肯定是将图转化为Trie树,这样可以求得字典序.然后,按照trie的层次求解.一直wa的原因在于将树转化为线性数据结构时要从原树遍历,从trie遍历就会wa.不同结点可能映射为t ...

  8. Maven、gradle、Ant、Eclipse IDE

    Maven.gradle.Ant.Eclipse IDE之间的关系 http://wenku.baidu.com/view/d33208810912a21615792910.html?from=sea ...

  9. C# 判断两张图片是否一致的快速方法

    #region 判断图片是否一致 /// <summary> /// 判断图片是否一致 /// </summary> /// <param name="img& ...

  10. ↗☻【HTML5秘籍 #BOOK#】第8章 使用CSS3

    开发商前缀-moz- Firefox-webkit- Chrome和Safari-ms- Internet Explorer-o- Opera 伪类创造的交互性虽好,但已经有点过时了.主要问题是—太突 ...