android四大和作用场景,Android:图解四种启动模式 及 实际应用场景讲解(示例代码)...

在一个项目中会包含着多个Activity,系统中使用任务栈来存储创建的Activity实例,任务栈是一种“后进先出”的栈结构。举个栗子,若我们多次启动同一个Activity,系统会创建多个实例依次放入任务栈中,当按back键返回时,每按一次,一个Activity出栈,直到栈空为止,当栈中无任何Activity,系统就会回收此任务栈。

上面这个例子中的Activity并没有设置启动模式,你会发现多次启动同一个Activity,而系统却创建了多个实例,白白浪费内存,这种情况Android早就替我们考虑好了。Android为Activity 的创建提供了4种启动模式,而根据实际应用场景的不同,为Activity 选择不同的启动模式,最大化减少了每次都需要在栈中创建一个新的Activity的压力,减少内存使用。

启动模式的具体说明和使用场景?下面根据这篇博文来一一解惑。

一. Android启动模式详解

8e397712811c4f719b6ce5ce9aaa10f6.jpg

1. Standard 标准模式

说明: Android创建Activity时的默认模式,如果没有为Activity设置启动模式的话,默认为标准模式。每次启动一个Activity都会重新创建一个新的实例入栈,不管这个实例是否存在。

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

举例:此时Activity 栈中以此有A、B、C三个Activity,此时C处于栈顶,启动模式为Standard 模式。若在C Activity中添加点击事件,需要跳转到另一个同类型的C Activity。结果是另一个C Activity进入栈中,成为栈顶。

1ebdf744b079480a8eddba2f7bad1c1a.jpg

2. SingleTop 栈顶复用模式

说明:分两种处理情况:需要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity,不会再创建新的Activity;若需要创建的Activity不处于栈顶,此时会重新创建一个新的Activity入栈,同Standard模式一样。

生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,因为它并没有发生改变,但是一个新的方法 onNewIntent会被回调(Activity被正常创建时不会回调此方法)。

举例:此时Activity 栈中以此有A、B、C三个Activity,此时C处于栈顶,启动模式为SingleTop 模式。情况一:在C Activity中添加点击事件,需要跳转到另一个同类型的C Activity。结果是直接复用栈顶的C Activity。情况二:在C Activity中添加点击事件,需要跳转到另一个A Activity。结果是创建一个新的Activity入栈,成为栈顶。

099469cb5e9a48d6b5f2a75607b456ed.jpg

3. SingleTask 栈内复用模式

说明:若需要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其它Activity全部销毁,使它成为栈顶。

生命周期:同SingleTop 模式中的情况一相同,只会重新回调Activity中的 onNewIntent方法

举例:此时Activity 栈中以此有A、B、C三个Activity,此时C处于栈顶,启动模式为SingleTask 模式。情况一:在C Activity中添加点击事件,需要跳转到另一个同类型的C Activity。结果是直接用栈顶的C Activity。情况二:在C Activity中添加点击事件,需要跳转到另一个A Activity。结果是将A Activity上面的B、C全部销毁,使A Activity成为栈顶。

9dc093efb5a74d98b194001ec971d6e9.jpg

4. SingleInstance 单实例模式

说明: SingleInstance比较特殊,是全局单例模式,是一种加强的SingleTask模式,它除了具有它所有特性外,还加强了一点:具有此模式的Activity只能单独位于一个任务栈中。这个常用于系统中的应用,例如Launch、锁屏键的应用等等,整个系统中只有一个!所以在我们的应用中一般不会用到,了解即可。

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

二.启动模式的使用方式

1. 在 Manifest.xml中指定Activity启动模式

一种静态的指定方法,在Manifest.xml文件中声明Activity的同时指定它的启动模式,这样在代码中跳转时会按照指定的模式来创建Activity。例子如下:

2. 启动Activity时,在Intent中指定启动模式去创建Activity

一种动态的启动模式,在new 一个Intent后,通过Intent的addFlags方法去动态指定一个启动模式。例子如下:

Intent intent = new Intent();

intent.setClass(context, MainActivity.class);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent);

注意:以上两种方式都可以为Activity指定启动模式,但是二者还是有区别的。

(1)优先级:动态指定方式即第二种比第一种优先级要高,若两者同时存在,以第二种方式为准。

(2)限定范围:第一种方式无法为Activity直接指定 FLAG_ACTIVITY_CLEAR_TOP 标识,第二种方式无法为Activity指定 singleInstance 模式。

三. Activity 的 Flags

标记位既可以设定Activity的启动模式,如同上面介绍的,在动态指定启动模式,比如 FLAG_ACTIVITY_NEW_TASK 和 FLAG_ACTIVITY_SINGLE_TOP 等。它还可以影响Activity 的运行状态 ,比如 FLAG_ACTIVITY_CLEAN_TOP 和 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 等。下面介绍几个主要的标记位,切勿死记,理解几个即可,需要时再查官方文档。

1. FLAG_ACTIVITY_NEW_TASK

作用是为Activity指定 “SingleTask”启动模式,跟在AndroidMainfest.xml指定效果相同。

2. FLAG_ACTIVITY_SINGLE_TOP

作用是为Activity指定 “SingleTop”启动模式,跟在AndroidMainfest.xml指定效果相同。

3. FLAG_ACTIVITY_CLEAN_TOP

具有此标记位的Activity,启动时会将与该Activity在同一任务栈的其它Activity出栈,一般与SingleTask启动模式一起出现。它会完成SingleTask的作用,但其实SingleTask启动模式默认具有此标记位的作用

4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

具有此标记位的Activity不会出现在历史Activity的列表中,使用场景:当某些情况下我们不希望用户通过历史列表回到Activity时,此标记位便体现了它的效果。它等同于在xml中指定Activity的属性:

android:excludeFromRecents="trure"

四. 启动模式的实际应用场景

这四种模式中的Standard模式是最普通的一种,没有什么特别注意,而SingleInstance模式是整个系统的单例模式,在我们的应用中一般不会应用到,所以,这里就具体讲解 SingleTop 和 SingleTask模式的运用场景:

1. SingleTask模式的运用场景

最常见的应用场景就是保持我们应用开启后只有一个Activity的实例,最典型的例子就是应用中展示的主页(Home页)。假设用户在主页跳转到其它页面,执行多次操作后想返回到主页,如果不使用SingleTask模式,在点击返回的过程中会多次看到主页,这明显就是设计不合理了。

2. SingleTop模式的运用场景

如果你在当前的Activity中又要启动同类型的Activity,此时建议将此类型Activity的启动模式指定为SingleTop,可以减少Activity的创建,节省内存!

3. 注意:复用Activity时的生命周期回调

这里还需要考虑一个Activity跳转时携带页面参数的问题。

因为当一个Activity设置了SingleTop或者SingleTask模式后,跳转此Activity出现复用原有Activity的情况时,此Activity的onCreate方法将不会再次执行!onCreate方法只会在第一次创建Activity时被执行。

而一般onCreate方法中会进行该页面的数据初始化、UI初始化,如果页面的展示数据无关页面跳转传递的参数,则不必担心此问题,若页面展示的数据就是通过getInten() 方法来获取,那么问题就会出现:getInten()获取的一直都是老数据,根本无法接收跳转时传送的新数据!下面,通过一个例子来详解:

Manifest.xml

android:launchMode="singleTop"

android:screenOrientation="portrait" />

public class CourseDetailActivity extends BaseActivity{

......

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_course_detail_layout);

initData();

initView();

}

//初始化数据

private void initData() {

Intent intent = getIntent();

mCourseID = intent.getStringExtra(COURSE_ID);

}

//初始化UI

private void initView() {

......

}

......

}

以上代码中的CourseDetailActivity在配置文件中设置了启动模式是SingleTop模式,根据上面启动模式的介绍可得知,当CourseDetailActivity处于栈顶时,再次跳转页面到CourseDetailActivity时会直接复用原有的Activity,而且此页面需要展示的数据是从getIntent()方法得来,可是initData()方法不会再次被调用,此时页面就无法显示新的数据。

当然这种情况系统早就为我们想过了,这时我们需要另外一个回调 onNewIntent(Intent intent)方法,此方法会传入最新的intent,这样我们就可以解决上述问题。这里建议的方法是重新去setIntent,然后重新去初始化数据和UI,代码如下所示:

/*

* 复用Activity时的生命周期回调

*/

@Override

protected void onNewIntent(Intent intent) {

super.onNewIntent(intent);

setIntent(intent);

initData();

initView();

}

这样,在一个页面中可以重复跳转并显示不同的内容。

启动模式其实是初学Android时会学到的知识点,以前也是一知半懂,有些知识点其实跟设计模式一样,你不去使用而只是学习并非可以掌握到精髓,只有真正去使用才会将这些变成你自己的,文章部分内容参考了《Android开发艺术探索》,好书推荐。

最近在使用启动模式,特此来小小总结一番,网上关于此类的文章也有许多,但是多总结总结还是有益无害的。

欢迎指错~

希望对你们有帮助 :)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值