应用程序组件-------Activity(一)

本文详细介绍了Android应用程序中的核心组件——Activity,包括Activity的定义与创建、生命周期管理、启动模式及注意事项等。适合Android开发者深入理解Activity的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

APP ──── 是“Android应用程序”的简称。官方解释是:使用Java语言开发,Android SDK 工具编译代码,以及任意数据并连同相关资源打包进一个Android 包内,它是一个以.apk 为后缀的压缩文件。这个.apk文件就用于在Android设备上安装这个程序。 
Android操作系统是一个多用户的Linux系统,其中的每一个应用程序都是一个独立的用户。每一个进程有它主机的Dalvik虚拟机 (VM), 所以一个应用程序的代码会独立与其它的应用程序在它自己的Linux进程中运行。Android会在一个应用程序的任何一个组件需要被调用的时候启动这个进程。然后,当没有任何组件被调用或者系统需要为其它应用程序回收内存的时候,就会关闭这个进程。
所以组件是一个Android程序至关重要的构建模块。每一个组件都是系统进入你的应用的不同途径。但并不是所有的组件都是用户进入程序的真实入口,其中一些要依赖于其它组件, 但是每一个组件都以自己独有的形式存在,并发挥特殊的作用;每一个组件都是一个唯一的模块,帮助你实现程序的各种行为。
Android程序有四种不同的应用程序组件,分别为Activity,Service,Content provider,Broadcast receiver。每一种组件都有其唯一的目的并且有独有的生命周期,这个生命周期定义了附件被创建和销毁的方式。下面首先介绍四种类型的应用程序组件Activity,以及Activity在开发过程中注意点和易忽视点。
一、Activity定义,创建。
1、可继承Activity
一个 activity 为一个用户交互提供一个单独的界面。一般开发者通过继承Activity来创建自己的activity。sdk中可以继承 AppCompatActivity, ActionBarActivity,
FragmentActivity, PreferenceActivity, Activity。他们的不同简单来说:
  • FragmentActivity 是support v4 包下的 ,兼容2.x模式下使用Fragment
  • AppCompatActivity 是 support v7 包下的, 兼容2.x模式下使用Fragment和ActionBar,
  • ActionBarActivity是AppCompatActivity过时产品。如果3.0以上直接继承Activity,便可使用Fragment和ActionBar。
  • PreferenceActivity是android提供的对系统信息和配置进行自动保存的Activity,它通过SharedPreference方式将信息保存在XML 文件当中。使用PreferenceActivity不需要我们对SharedPreference进行操作,系统会自动对Activity 的各种View上的改变进行保存PreferenceActivity 的使用可参考:
如今大多以直接继承AppCompatActivity 来创建一个Activity.
2、创建半透明 dialogActivity
想使Activity有对话框那样效果可以在Androidmanifest中添加 android:style/Theme.Dialog 的主题特性,例如这样: 
<activity android:name=”MyDialogActivity”  
       android:theme=”@android:style/Theme.Dialog”>  
</activity>  
如果你觉得上面不足以满足你的需求想实现半透明的, 圆角的,不妨可以试试自定义对话框的style
<style name="MyDialogStyle">  
        <item name="android:windowBackground">@android:color/transparent</item>  
        <item name="android:windowFrame">@null</item>  
        <item name="android:windowNoTitle">true</item>  
        <item name="android:windowIsFloating">true</item>  
        <item name="android:windowIsTranslucent">true</item>  
        <item name="android:windowContentOverlay">@null</item>  
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>  
        <item name="android:backgroundDimEnabled">true</item>  
</style>  
然后在Manifest文件中对DialogActivity进行注册,并使用上面自定义MyDialogStyle样式就可以了,
二、Activity生命周期
1、 Activity的生命周期很简单。如图所示:

  • 启动Activity: onCreate()—>onStart()—>onResume(),Activity进入running状态。
  • 被其它Activity部分遮盖: onPause(),仍有部分可见,还在内存中。可被回收。同时在onPause里持久化数据。不是在onSaveInstanceState中。
  • 从onPause回到前台:onResume(),然后再次进入running态。
  • 被其它Activity遮盖(HOME,锁屏,启动其它Activity等): onPause()->onStop()。此时仍可能在内存中,系统内存不足时,可被回收。
  • 在Stopped时,用户再次点击进入Activity:如果已被回收,则onCreate()->onStart()->onResume(),没被回收onRestart()->onStart()->onResume()
  • 注意当执行完onDestroy()后,该activity还在内存中,并未有被销毁或被值为null.
2、Activity保存 ,恢复数据注意点:
  • 系统一般在 onStop() 或 onPause()前调用onSaveInstanceState(),而不是onDestory()前一步,因为用户可能就是退出。
  • 不要忘记调用super.onSaveInstanceState();onSaveInstanceState只保存一些ui信息,并且不保证一定被调用,持久化的数据一定不要保存在这里。而应在onPause中。
  • 要留意
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
}
此方法在恢复数据的时候调用,千万不要把它当做 onCreate(Bundle savedInstanceState)方法,去做view的初始化。本来onSaveInstanceState和onRestoreInstanceState方法是一对拯救灾难的方法,它们不在“正常“的Activity生命周期中,只有一些突发异常情况才会触发它们, 比如横竖屏切换、按Home键等。当API 21后增加了PersistableBundle参数, 令这些方法有了系统关机重启后数据恢复的能力。 而如果要重写这个方法, 还需在Manifest中的activity设置属性: android:persistableMode="persistAcrossReboots"
然后在activity中直接用上述的三个方法即可。 另外注意API版本是21及以上。

三、Activity启动模式

1、task(任务)与Back Stack(回退栈)

讲启动模式就要理解好Task(任务)与Back Stack(回退栈)的概念:
  • 所有的 activity 都属于一个task
  • task 是多个 activity 的集合,用户进行操作时将与这些 activity 进行交互。 这些 activity 按照启动顺序排队存入一个栈(即“back stack”)。
  • task 可以转入后台,并会保存每个 activity 的状态,这样用户运行其它 task 时就不会丢失当前的工作了。
对于Activity在Task上的设置,你可以在清单文件注册时使用的 <activity> 属性主要有:
可用的 intent 标志主要有:
属性指明了 activity 启动 task 的方式。
(1)standard:标准模式(默认)不复用
(2)singleTop:栈顶复用模式
(3)singleTask:栈内复用模式(会清空目标activity上面的其它activity)
    singleTask自带clearTop效果:若待启动的Activity位于它想在的栈中(但不在栈顶),则系统会把它上面的Activity全部出栈,让待启动Activity的实例“提升”到栈顶。
(4)singleInstance:单实例模式(独立占用一个任务栈方式)
    这是一种加强的singleTask模式。它除了具有singleTask的所有特性外,还加强了一点:具有此种模式的Activity所在的任务栈中只能有它一个Activity。系统总是会为以singleInstance模式启动的Activity创建一个新的任务栈,再创建一个它的实例放进去。

3、allowTaskReparenting
    最后我们介绍一下allowTaskReparenting属性:当App A启动了App B的某个Activity后,若被启动Activity的allowTaskReparenting属性为true,那么当App B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈。因为实际上App B中的Activity的TaskAffinity属性为App B的包名,所以它本应属于B的任务栈,但App B此时未启动,所以它暂时在A的任务栈中待着。当我们一旦把相应Activity的allowTaskReparenting属性设为true时,待到时 机成熟(App B被启动),这个Activity就会去本该属于它的地方。


如果传给 startActivity() 的 intent 包含了 FLAG_ACTIVITY_NEW_TASK 标志,则系统会查找另一个 task 并将新 activity 放入其中。这时经常会新开一个任务,但并非一定如此。 如果一个已有 task 的 affinity 值与新 activity 的相同,则 activity 会放入该 task。 如果没有,则会新建一个新 task。
PS: 当一个 activity 的allowTaskReparenting属性设为 "true"
这种情况下,当某个 task 进入前台时,activity 的 affinity 值又与其相同,则它可以从启动时的 task 移入这个 task 中。

提示: 如果一个 .apk 文件中包含了多个“application”,你可能需要用 taskAffinity 属性来指定每个“application”中 activity 的 affinity 值。

如果 task 中根 activity 的此属性设为 "true" ,则默认的清理方式不会进行。即使过了很长时间,task 中所有的 activity 也都会保留在栈中。
如果 task 中根 activity 的此属性设为 "true",则只要用户离开并再次返回该 task,栈就会被清理至根 activity。也就是说,正好与alwaysRetainTaskState相反。用户每次返回 task 时看到的都是初始状态,即使只是离开一会儿。
此属性类似于clearTaskOnLaunch,只是它只对一个 activity 有效,不是整个 task。这能让任何一个 activity 消失,包括 根 activity。如果 activity 的此属性设为 "true",则只会保留 task 中当前 session 所涉及的内容。如果用户离开后再返回 task,它就不存在了。


在要启动 activity 时,你可以在传给 startActivity() 的 intent 中包含相应标志,以便修改 activity 与 task 的默认关系。这个标志可以修改的默认模式包括:
在新的 task 中启动 activity。如果要启动的 activity 已经运行于某 task 中,则那个 task 将调入前台,最后保存的状态也将恢复,activity 将在onNewIntent()中接收到这个新 intent。
这个过程与前一节所述的"singleTask"launchMode模式值相同。
如果要启动的 activity 就是当前 activity(位于back stack 顶),则已存在的实例将接收到一个onNewIntent()调用,而不是创建一个 activity 的新实例。
这个过程与前一节所述的 "singleTop"launchMode模式值相同。
如果要启动的 activity 已经在当前 task 中运行,则不再启动一个新的实例,且所有在其上面的 activity 将被销毁,然后通过onNewIntent()传入 intent 并恢复 activity(不在栈顶)的运行。
此种模式在launchMode中没有对应的属性值。
FLAG_ACTIVITY_CLEAR_TOP 常与 FLAG_ACTIVITY_NEW_TASK 一起使用。这表示先定位其它 task 中已存在的 activity,再把它放入可以响应 intent 的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值