Android基础-Activity

2019-06-12  本文已影响0人  VitaAin

Google Doc: https://developer.android.google.cn/guide/components/activities/

一、Activity生命周期

Activity生命周期.jpg

当一个 Activity 启动另一个 Activity 时,第一个 Activity 暂停并停止(但如果它在后台仍然可见,则不会停止)时,同时系统会创建另一个 Activity,在创建第二个 Activity 前,第一个 Activity 不会完全停止。更确切地说,启动第二个 Activity 的过程与停止第一个 Activity 的过程存在重叠。

当 Activity A 启动 Activity B 时:

  1. Activity A 的 onPause() 方法执行。
  2. Activity B 的 onCreate()onStart()onResume() 方法依次执行。(Activity B 现在具有用户焦点。)
  3. 然后,如果 Activity A 在屏幕上不再可见,则其 onStop() 方法执行。

此时在Activity B中按下Back键,则:

  1. B.onPause()->A.onRestart->A.onStart->A.onResume-> B.onStop->B.onDestroy。

二、Activity异常生命周期

1 相关系统配置改变导致Activity被杀死并重新创建(一般指横竖屏切换)

Activity restore_instance.png

2 内存不足导致低优先级的Activity被杀死

当系统内存不足的时候,系统就会按照一定的优先级去杀死目标Acitivity的进程来回收内存,并且此时Activity的onSaveInstanceState方法会被调用来存储数据,并在后续Activity恢复时调用onRestoreInstanceState方法来恢复数据


三、Activity销毁重建

当系统配置发生变化后,Activity会被重建。

如果不想Activity在屏幕旋转后导致销毁重建时,可以设置configChange=“orientation”;当SDK版本大于13时,还需额外添加一个“screenSize”的值。
设置了这两个参数后,当横竖屏切换时,Activity不会再重建并且也不会调用onSaveInstanceState方法和onRestoreInstanceState方法,而是会回调onConfigurationChanged方法。


四、Activity通信

  1. 通过将数据封装在Bundle对象中 ,然后在Intent跳转的时候携带Bundle对象
    该方法可以传递基本数据类型和String类型的数据,如果传递的是对象就需要进行序列化。

  2. 类静态变量
    通过public static定义Activity的静态变量然后在其他Activity使用类名.变量名传递。

  3. Application
    通过在Application 中的全局静态变量来实现。

  4. EventBus
    当传输的数据量较大的时候Parcelable虽然很便捷,但是会出现异常TransactionTooLargeException。此时可以用插件EventBus。

EventBus 使用的是发布-订阅者模型,发布者通过EventBus发布事件,订阅者通过EventBus订阅事件。当发布者发布事件时,订阅该事件的订阅者的事件处理方法将被调用。


五、Activity启动模式

Activity启动模式分四种:Standard 标准模式,SingleTop 栈顶复用模式、SingleTask 栈内复用模式、SingleInstance 单实例模式。

1 Standard 标准模式

每次启动一个Activity,都会又一次创建一个新的实例入栈,无论这个实例是否存在。

生命周期:

每次被创建的实例Activity的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。

举例:

Activity栈中已有A、B、C三个Activity,C处于栈顶。若从C Acticity跳转到另一个C Activity,结果是新建一个C Activity入栈,成为栈顶。

Activity启动模式-Standard.png

2 SingleTop 栈顶复用模式

生命周期:

情况1下,栈顶Activity直接被复用,它的onCreate、onStart不会被调用,因为它并没有发生改变,但onNewIntent会被调用(Activity被正常创建时不会回调此方法)。

举例:

Activity栈中已有A、B、C三个Activity,C处于栈顶。情况一:从C跳转到另一个C,结果是直接复用栈顶的C,不再新建;情况二:从C跳转到A,结果是新建一个A入栈,成为栈顶。

Activity启动模式-SingleTop.png
使用场景:

假设在当前的Activity中要启动同类型的Activity,此时建议将该Activity指定为SingleTop模式,能够降低Activity的创建,节省内存。

3 SingleTask 栈内复用模式

若需要创建的Activity已处于栈中,不会再新建Activity,而是将存在栈中的Activity上面的其他所有Activity销毁,使它成为栈顶。

生命周期:

同SingleTop情况一同样,仅会回调Activity的onNewIntent方法。

举例:

Activity栈中已有A、B、C三个Activity,C处于栈顶。情况一:从C跳转到C,则直接复用栈顶的C;情况二:从C跳转到A,则将A上面的B、C销毁,使A成为栈顶。

Activity启动模式-SingleTask.png
使用场景:

最常见的应用场景就是保持应用开启后仅仅有一个Activity的实例。
比如:应用中展示的主页,假设用户在主页跳转到其他页面,多次操作后想返回到主页,假设不使用SingleTask模式,在点击返回的过程中会多次看到主页,不合理。

4 SingleInstance 单实例模式

全局单例模式,加强的SingleTask。具有此模式的Activity仅仅能单独位于一个任务栈中。经常适用于系统中的应用,比如Launch、锁屏键的应用等,整个系统中仅有一个。

举例:

A Activity是该模式,启动A后,系统会为它创建一个单独的任务栈,由于栈内复用的特性,新的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁。

六、使用方式

使用方法有两种:

  1. AndroidManifest.xml中为Activity指定launchMode。
  2. 动态指定,通过Intent的addFlags方法动态指定启动模式。
优先级:

第2种比第1种优先级高,若两者同时存在,以2为准

限定范围:

第1种无法为Activity直接指定FLAG_ACTIVITY_CLEAR_TOP标识;
第2种无法为Activity指定SingleInstance模式。

注意:须考虑Activity跳转时携带页面参数的问题

当一个Activity设置了SingleTop或者SingleTask模式后,跳转此Activity出现复用原有Activity的情况时,此Activity的onCreate方法将不会再调用。onCreate方法仅会在第一次创建Activity时被调用。
而一般onCreate方法中会进行该页面的数据初始化、UI初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题;若页面展示的数据就是通过getIntent() 方法来获取,那么问题就会出现:getIntent()获取的一直都是老数据,根本无法接收跳转时传送的新数据!
这时我们需要另外一个回调 onNewIntent(Intent intent)方法。此方法会传入最新的intent,这样我们就能够解决上述问题。这里建议的方法是再次调用setIntent。然后重新初始化数据和UI。

七、相关Flags

1 FLAG_ACTIVITY_NEW_TASK

为Activity指定SingleTask启动模式,与AndroidManifest.xml指定效果相同。

2 FLAG_ACTIVITY_SINGLE_TOP

为Activity指定SingleTop启动模式,与AndroidManifest.xml指定效果相同。

3 FLAG_ACTIVITY_CLEAN_TOP

具有此标记的Activity,启动时会将与其同栈的其他Activity出栈。一般与SingleTask启动模式一起出现。它会完毕SingleTask的作用,但事实上SingleTask启动模式默认具有此标记的作用。

4 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

具有此标记的Activity不会出现在Activity列表中。
使用场景:某些情况下不希望用户通过历史列表回到某个Activity时,此标记便可以实现该效果。
等同于AndroidManifest.xml中指定Activity属性:android:excludeFromRecents="true"


八、监听Activity生命周期

在Application中调用 registerActivityLifecycleCallbacks(),通过 ActivityLifecycleCallbacks 接口的实现,完成对Activity各个生命周期信息的采集。
比如哪个Activity在什么时间处于onCreate、onStop等等,进而统计出Activity的使用时间和使用次数。

上一篇下一篇

猜你喜欢

热点阅读