activity类处于android.app包中,继承关系:

extends ContextThemeWrapper

implements LayoutInflater.Factory2 Window.Callback KeyEvent.CallbackView.OnCreateContextMenuListenerComponentCallbacks2

java.lang.Object
   ↳ android.content.Context
     ↳ android.content.ContextWrapper
       ↳ android.view.ContextThemeWrapper
         ↳ android.app.Activity

Activity 简介

Activity是什么呢?Activity是一个应用程序提供与用户进行交流的界面。每个Activity都可以通过布局来呈现自己的用户界面,一个应用程序通常包括很多Activity,其中有一个被称为主Activity,这是程序第一次启动所展示的,例如很多程序都有的欢迎界面。将Activity设置成主Activity可以通过配置AndroidManifest.xml文件,将如下代码复制到activity的标签之中:

    <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

一个Activity可以启动另一个Activity来实现不同的表现,当一个Activity启动后,它被压入一个stack中,获得焦点,当用户按了back按钮后,当前的Activity从stack中弹出(即被destroyed),先前的Activity被释放从新获得焦点。这些涉及到Activity的生命周期,后面将进行讨论。

怎么创建一个Activity呢?通过继承父类Activity,来创建一个属于自己的Activity,这要求你需要实现Activity父类的回调方法,这些方法在Activity的生命周期中的不同状态被调用,如:创建,暂停,释放,销毁。其中有两个最重要的回调方法:

1.onCreate()

  这个方法在Activity被创建时被调用,在这个方法应该初始化各个控件,通过调用setContentView(R.layout.xxx)方法定义布局来展现Activity的用户界面,其中R.layout.xxx为Activity的XML布局文件。

2.onPause()

  这个方法在用户离开当前Activity时被调用,这就需要在这个方法中保存用户与当前Activity的会话,比如在EditText中输入的值。用户在返回当前Activity时,还应该显示离开时所填写的值。

当然每创建一个Activity都需要在AndroidManifest.xml文件中注册一个相应的Activity。如:创建的Activity的类名为:MyActivity则在文件中需添加如下代码:

     <activity
android:name=".SecondActivity"
android:label="@string/app_name"
>
</activity>

Activity 的状态及状态间的转换:

在 android 中,Activity 拥有四种基本状态:

  1. Active/Runing一个新 Activity 启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
  2. Paused 当 Activity 被另一个透明或者 Dialog 样式的 Activity 覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。
  3. Stoped 当 Activity 被另外一个 Activity 覆盖、失去焦点并不可见时处于
    Stoped
    状态。
  4. Killed Activity 被系统杀死回收或者没有被启动时处于 Killed状态。

当一个 Activity 实例被创建、销毁或者启动另外一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作。下图说明了 Activity 在不同状态间转换的时机和条件:

图 1. Activity 的状态转换

如上所示,Android 程序员可以决定一个 Activity 的“生”,但不能决定它的“死”,也就时说程序员可以启动一个 Activity,但是却不能手动的“结束”一个 Activity。当你调用Activity.finish()方法时,结果和用户按下 BACK 键一样:告诉 Activity Manager 该 Activity 实例完成了相应的工作,可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity 并重新入栈,同时原 Activity
被压入到栈的第二层,从 Active 状态转到 Paused 状态。例如:从 Activity1 中启动了 Activity2,则当前处于栈顶端的是 Activity2,第二层是 Activity1,当我们调用Activity2.finish()方法时,Activity Manager 重新激活 Activity1 并入栈,Activity2 从 Active 状态转换 Stoped 状态,Activity1. onActivityResult(int requestCode, int
resultCode, Intent data)
方法被执行,Activity2 返回的数据通过data参数返回给 Activity1。

Activity 栈

Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示:

图 2. Activity 的状态与它在栈中的位置关系

如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置。

Activity 生命周期

android.app.Activity类中,Android 定义了一系列与生命周期相关的方法,在我们自己的 Activity 中,只是根据需要复写需要的方法.

Activity生命周期图:

下面我们通过一个实例来说明Activity生命周期。新建工程,编写如下代码:

public class MainActivity extends AppCompatActivity {

    private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "onCreate");
} @Override
protected void onResume() {
super.onResume(); Log.i(TAG, "onResume");
} @Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart");
} @Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause");
} @Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop");
} @Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
}

我们通过记录操作和打印日志的方式来看看Activity的生命周期过程;

1、  运行

看到如下打印日志:

11-26 09:09:33.665 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onCreate

11-26 09:09:33.665 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStart

11-26 09:09:33.665 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onResume

2、按下返回按键:

11-26 09:30:20.097 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onPause

11-26 09:30:20.637 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStop

11-26 09:30:20.637 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onDestroy

3、长按Home键,弹出最近打开过的应用程序,点击ActivityDemo

11-26 09:31:07.341 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onCreate

11-26 09:31:07.341 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStart

11-26 09:31:07.341 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onResume

4、按Home键

11-26 09:31:44.649 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onPause

11-26 09:31:45.173 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStop

5、在AllList中点击打开

11-26 09:32:11.793 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onRestart

11-26 09:32:11.793 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStart

11-26 09:32:11.793 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onResume

通过日志信息,我们可以看到。

Activity的启动过程:onCreate—onStart—onResume;

下返回键时:onPause—onStop—onDestroy 正如上面说是,当按下返回键时,此Activity弹出栈,程序销毁。确实如此;

我们再次 打开时的启动过程又回到onCreate—onStart—onResume。OK;

启动之后按下Home键,回到Launcher,查看打印信息:onPause—onStop;

再次打开的运行过程:onRestart—onStart—onResume;

我们通过对Activity的各种操作,构成了Activity的生命周期,我们看到无论对Activity做如何的操作,都会接收到相关的回调方法,那么我们在开发的过程中通过这些回调方法就可以写工作,比如说释放一些重量级的对象,网络连接,数据库连接,文件读等等。

以下是各个方法的详细说明:

onCreate():当 activity 第一次创建时会被调用。在这个方法中你需要完成所有的正常静态设置 ,比如创建一个视图( view )、绑定列表的数据等等。如果能捕获到 activity 状态的话,这个方法传递进来的 Bundle 对象将存放了 activity 当前的状态。调用该方法后一般会调用 onStart() 方法。

onRestart():在 activity 被停止后重新启动时会调用该方法。其后续会调用 onStart 方法。

onStart() 当 activity 对于用户可见前即调用这个方法。如果 activity回到前台则接着调用 onResume() ,如果 activity 隐藏则调用onStop()

onResume():在 activity 开始与用户交互前调用该方法。在这时该activity 处于 activity 栈的顶部,并且接受用户的输入。其后续会调用 onPause() 方法。

onPause():在系统准备开始恢复其它 activity 时会调用该方法。这个方法中通常用来提交一些还没保存的更改到持久数据 中,停止一些动画或其它一些耗 CPU 的操作等等。无论在该方法里面进行任何操作,都需要较快速完成,因为如果它不返回的话,下一个 activity 将无法恢复出来。如果 activity 返回到前台将会调用 onResume() ,如果 activity 变得对用户不可见了将会调用onStop() 。

onStop():在 activity 对用户不可见时将调用该方法。可能会因为当前 activity 正在被销毁,或另一个 activity (已经存在的activity 或新的 activity )已经恢复了正准备覆盖它,而调用该方法。如果 activity 正准备返回与用户交互时后续会调用onRestart ,如果 activity 正在被释放则会调用 onDestroy 。

onDestroy():在 activity 被销毁前会调用该方法。这是 activity 能接收到的最后一个调用。可能会因为有人调用了 finish 方法使得当前activity 正在关闭,或系统为了保护内存临时释放这个 activity的实例,而调用该方法。你可以用 isFinishing 方法来区分这两种不同的情况。

启动另外一个 Activity

要启动一个新的Activity,我们可以通过调用 startActivity来启动例:

 Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
startActivity(intent);

注意:OtherActivity同样在 AndroidManifest.xml 中定义。

Activity 之间通信使用 Intent 通信

在 Android 中,不同的 Activity 实例可能运行在一个进程中,也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在 Activity 之间传递消息。Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。

在上面的实例中通过 Activity. startActivity(intent)启动另外一个 Activity 的时候,我们在 Intent 类的构造器中指定了“收件人地址”。

我们通过 bundle对象来传递信息,bundle维护了一个 HashMap<String, Object>对象,将我们的数据存贮在这个 HashMap 中来进行传递。但是像上面这样的代码稍显复杂,因为 Intent 内部为我们准备好了一个bundle,所以我们也可以使用这种更为简便的方法:

Intent intent =new Intent(MainActivity.this,OtherActivity.class);
intent.putExtra("boolean_key", true);
intent.putExtra("string_key", "string_value");
startActivity(intent);

接收:

 Intent intent=getIntent();
intent.getBooleanExtra("boolean_key",false);
intent.getStringExtra("string_key");

Activity 的 Intent Filter

ntent Filter 描述了一个组件愿意接收什么样的 Intent 对象,Android 将其抽象为 android.content.IntentFilter 类。在 Android 的 AndroidManifest.xml 配置文件中可以通过<intent-filter >节点为一个 Activity 指定其 Intent Filter,以便告诉系统该 Activity 可以响应什么类型的 Intent。

当程序员使用 startActivity(intent) 来启动另外一个 Activity 时,如果直接指定 intent 了对象的 Component 属性,那么 Activity Manager 将试图启动其 Component 属性指定的 Activity。否则 Android 将通过 Intent 的其它属性从安装在系统中的所有 Activity 中查找与之最匹配的一个启动,如果没有找到合适的 Activity,应用程序会得到一个系统抛出的异常。这个匹配的过程如下:

图 4. Activity 种 Intent Filter 的匹配过程

Action 匹配

Action 匹配Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的 Activity 定义时可以在其<intent-filter >节点指定一个 Action 列表用于标示 Activity 所能接受的“动作”,例如:

 <intent-filter >
<action android:name="android.intent.action.MAIN" />
<action android:name="com.zy.myaction" />
……
</intent-filter>

如果我们在启动一个 Activity 时使用这样的 Intent 对象:

 Intent intent =new Intent();
intent.setAction("com.zy.myaction");

那么所有的 Action 列表中包含了“com.zy.myaction”的 Activity 都将会匹配成功。

Android 预定义了一系列的 Action 分别表示特定的系统动作。这些 Action 通过常量的方式定义在 android.content. Intent中,以“ACTION_”开头。我们可以在 Android 提供的文档中找到它们的详细说明。

URI 数据匹配

一个 Intent 可以通过 URI 携带外部数据给目标组件。在 <intent-filter >节点中,通过 <data/>节点匹配外部数据。

mimeType 属性指定携带外部数据的数据类型,scheme 指定协议,host、port、path 指定数据的位置、端口、和路径。如下:

 <data android:mimeType="mimeType" android:scheme="scheme"
android:host="host" android:port="port" android:path="path"/>

如果在 Intent Filter 中指定了这些属性,那么只有所有的属性都匹配成功时 URI 数据匹配才会成功。

Category 类别匹配

<intent-filter >节点中可以为组件定义一个 Category 类别列表,当 Intent 中包含这个列表的所有项目时 Category 类别匹配才会成功。

一些关于 Activity 的技巧

锁定 Activity 运行时的屏幕方向

Android 内置了方向感应器的支持。在 G1 中,Android 会根据 G1 所处的方向自动在竖屏和横屏间切换。但是有时我们的应用程序仅能在横屏 / 竖屏时运行,比如某些游戏,此时我们需要锁定该 Activity 运行时的屏幕方向,<activity >节点的android:screenOrientation属性可以完成该项任务,示例代码如下:

 <activity android:name=".EX01"
android:label="@string/app_name"
android:screenOrientation="portrait">// 竖屏 , 值为 landscape 时为横屏
…………
</activity>

全屏的 Activity

要使一个 Activity 全屏运行,可以在其 onCreate()方法中添加如下代码实现:

 // 设置全屏模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 去除标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);

设置Activity 的 Title

setTitle("我的");

实现双击返回键退出功能:

private long exitTime = 0;

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){
if((System.currentTimeMillis()-exitTime) > 2000){
Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
System.exit(0);
}
return true;
}
return super.onKeyDown(keyCode, event);
}

部分来源:

http://www.ibm.com/developerworks/cn/opensource/os-cn-android-actvt/

Demo 下载:

Android Activity 详述的更多相关文章

  1. Android:Activity+Fragment及它们之间的数据交换.

    Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...

  2. Android Activity launchMode研究

    Android Activity launchMode研究 Activity的Launch mode一共有四种: standard, singleTop, singleTask, singleInst ...

  3. android Activity类中的finish()、onDestory()和System.exit(0) 三者的区别

    android Activity类中的finish().onDestory()和System.exit(0) 三者的区别 Activity.finish() Call this when your a ...

  4. Android Activity的生命周期简单总结

    Android Activity的生命周期简单总结 这里的内容参考官方的文档,这篇文章的目的不是去总结Activity是如何启动,如何创造,以及暂停和销毁的,而是从实际开发中分析在Activity各个 ...

  5. Android Activity返回键控制的两种方式

    Android Activity返回键监听的两种方式 1.覆写Activity的OnBackPressed方法 官方解释: Called when the activity has detected ...

  6. Android Activity和Fragment的转场动画

    Android Activity和Fragment的转场动画 Activity转场动画 Activity的转场动画是通过overridePendingTransition(int enterAnim, ...

  7. android Activity生命周期(设备旋转、数据恢复等)与启动模式

    1.Activity生命周期     接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行.暂停和停止三种状态,onCreate.onStart.onResume.o ...

  8. Android Activity的加载模式和onActivityResult方法之间的冲突

    前言 今天在调试程序时,发现在某一Activity上点击返回键会调用该Activity的onActivityResult()方法.我一开始用log,后来用断点跟踪调试半天,还是百思不得其解.因为之前其 ...

  9. Android Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法:

    Android Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法: 1. 基本作用: Activity的 onSaveInstan ...

随机推荐

  1. dns 服务器配置

    1.安装 named 2.配置如下文件: /etc/named.conf // 2 // named.conf 3 // 4 // Provided by Red Hat bind package t ...

  2. ios外包公司—北京动点软件分享:IOS工程自动打包并发布脚本实现

    前言 IOS的开发过程中,当需要给测试人员发布测试包的时候,直接使用xcode来做的效率是非常低下的.尤其是当有一点小改动需要重新出包时,那简直是个折磨的人的工作.通过一番研究后,遂决定写一系列脚本, ...

  3. LintCode "Backpack"

    A simple variation to 0-1 Knapsack. class Solution { public: /** * @param m: An integer m denotes th ...

  4. js setTimeout

    setTimeout用法 //每个0.5秒钟改变字体和背景颜色,字体一闪一闪的效果 var flag = 0; function start(){ var text = document.getEle ...

  5. rails里routes配置文件里的resources和resource的区别

    抄自 http://stackoverflow.com/questions/11356146/difference-between-resource-and-resources-in-rails-ro ...

  6. AngularJS PhoneCat代码分析

    转载自:http://www.tuicool.com/articles/ym6Jfen AngularJS 官方网站提供了一个用于学习的示例项目:PhoneCat.这是一个Web应用,用户可以浏览一些 ...

  7. iphone Dev 开发实例10:How To Add a Slide-out Sidebar Menu in Your Apps

    Creating the Xcode Project With a basic idea about what we’ll build, let’s move on. You can create t ...

  8. OAF_VO系列3 - Binding Style绑定方式

    在OAF VO开发中,Binding Style主要用于对VO的where clause做动态传值,总共有三种方式 1.       Oracle Named 2.       Oracle Posi ...

  9. MHI ,运动历史图像的的获取[下载自CSDN]

    #include "cv.h" #include "highgui.h" #include "stdlib.h" #include &quo ...

  10. 1.运行Android Studio,一直提示:Error running app: Instant Run requires 'Tools | Android | Enable ADB integration' to be enabled.

    1.解决问题办法:菜单栏,Tools -> Adnroid -> enable ADB integration勾上 2.暂时性的解决方案:在Android Studio中的:Prefere ...