当前位置: 首页 > news >正文

【Android】活动的正/异常生命周期和启动模式、标志位详解

活动正常情况下生命周期的分析

  1. 生命周期的介绍

    1.onCreate()

    • 活动被创建的时候调用,写一个初始化的操作:setcontentview()加载布局,初始化活动的所需数据

    2. onRestart()

    • 活动由不可见变得可见时
    • 一个活动执行完Onstop,又点开活动,就会执行
  2. OnStart()

    • 当开启活动时调用,此时活动已**经可见了,**但是未显示到前台上,无法交互,用户看不见
  3. onResume()

    • 当活动显示到前台上,开发过程中,与OnStart()不一样就是是不是在前台上;
  4. onpause()

    • 特殊情况:用户操作很快,退到Home后又立刻进入,会由此进入到Onresume()方法中;
    • 一般写一些轻量级的动画或者储存数据,但不能太耗时;
  5. onStop()

    • 不可见;调用完onpause()立刻就会调用;
    • 同样也不能做耗时操作;
    • 可能会调用onrestart();
  6. onDestory()

    • 做一些系统回收等收尾工作以及最终的资源释放;
  7. 线

    1. onCreate()-> OnStart() ->onResume()
    2. onpause()->onStop()->onRestart()->OnStart()退到桌面,如果是透明主题,不会调用onstop
    3. onpause()->onResume()
    4. back回退会执行onDestory()

  8. 拓展

ActivityRecord

  1. 一个activity的实例,包含了这个活动的所有信息;

Task

  1. 包含了很多个ActivityRecord的栈,这些活动通常属于一个app;

ActivityStack

  1. AMS中实现调度的重要工具,在android11之后会被其他取代;

  2. 定位

    1. 维护活动的任务以及返回栈
    2. 包含了很多Task的一个栈
  3. 实例

    ActivityStack (文件架)
    │
    ├── Task A (文件夹A): [MailListActivity] (邮件列表)
    └── Task B (文件夹B): [BrowserHomeActivity] (浏览器主页)
    

    点开了弹窗:邮件的信息

    那么就会把邮件从栈中移动到栈顶,并且打开信息界面

    ActivityStack (文件架)
    │
    ├── Task A (文件夹A): [MailListActivity, MailDetailActivity] <-- 用户看到这个
    └── Task B (文件夹B): [BrowserHomeActivity]
    

    按返回键:邮件的信息->邮件列表->浏览器主页

AcitvityThread

  1. 是程序的入口和应用组件的控制执行器,一个进程只有一个AcitvityThread

启动一个活动的流程:

  1. APPa通过startactivity()请求通过binder到达AMS;
  2. AMS经过效验之后,通过Binder,调用appb的进程的这个方法ApplicationThread.scheduleLaunchActivity()
  3. ApplicationThread(binder对象(AMSAcitvityThread的信使))收到请求之后,会转化成Message,通过H(hanlderAcitvityThread内部的消息分发中心))发送给主线程消息队列中
  4. H调用这个方法ActivityThread.handleLaunchActivity()
  5. 这时AcitvityThread开始执行创建Activity实例Activity.onCreate();

当一个活动切换的到另外一个活动时,先执行onpause方法,才会开始创建另外一个活动;

活动异常情况下(被系统回收、系统configuration发生改变导致活动被销毁重建)

系统configuration发生改变导致活动被销毁重建

  1. 系统会默认销毁立刻重建手机旋转;

  2. 执行onstop执行,会执行onSaveInstanceState()方法;执行onstart之后,会执行onRestoreInstanceState方法;

  3. 通过onSaveInstanceState()传递bundle参数,重建时OncreateonRestoreInstanceState都会收到bundle对象;区别就是Oncreate要判空;

  4. 只有即将系统被销毁和有机会重新显示的时候才会调用onSaveInstanceState(),异常情况下才会被触发;

  5. 系统会自动做一些view层面的数据存储和恢复:

    每个view都有这两个方法;

    父容器委托子元素的委托思想:活动被销毁会调用onSaveInstanceState(),然后活动委托window保存数据,window委托它的顶级容器viewgroup(DecorView),然后一一通知子元素去保存数据;

资源内存不足导致低优先级的Acitivity被杀死

  1. 优先级:

    1. 前台的活动;
    2. 可见但是不在前台的活动;
    3. 后台的活动;
  2. 系统会根据以上的优先级会杀死目标活动所在的进程,杀死之后可以通过以上两个方法去保存数据,没有四大组件的进程很容易被杀死;所以一些后台工作最好放在service从而使得进程有一定的优先级,避免被杀死;

当系统结构发生改变时自定义处理方式

  1. 通过一个方法android:configChandes = ""因为当发生改变时候,系统会自动销毁重建,如果设置了,就避免了销毁重建,也不会调用两个保存数据的方法;

  2. 参数

    常见的参数:

    1.locale: 当设备的本地位置发生了变化,一般指系统语言;
    2. orientation: 屏幕方向发生了变化;
    3. keyboardHidden: 键盘的可访问性发生了变化;

    特殊的两个参数:

    1. screenSize:如果Minsdktargetsdk同时小于13,当屏幕尺寸发生改变,如果不写不会导致重启,大于13的话不写就会重启;
    2. smallestScreenSize::如果Minsdktargetsdk同时小于13,当物理屏幕尺寸发生改变(外接了显示设备),如果不写不会导致重启,否则就会重启;

  3. 当自定义之后,那么就会调用方法onConfigurationChanded(Configuration newconfig)我们在此时做一些特殊的处理

Activity的启动模式

为啥需要启动模式

  1. 当活动一直出栈导致栈空,那么这个任务栈将会被系统回收;
  2. 如果没有启动模式,那么一个任务会被重复创建很多次,这显然不太符合我们某些特定要求的情况;

四种启动模式

Standard(标准模式)
  1. 如果是此模式,每次都会创建新的活动实例;

  2. 谁调用了此活动,那么这个活动就会出现在调用此活动的活动所在的任务栈中;

  3. 如果用ApplicationContext启动Standard模式的活动会报错:

    1. 启动该活动的不是一个活动,而是一个context,这个context是没有任务栈的,所以会报错;

    2. 解决方法是为活动指定标记位,使得启动的时候为它创建一个新的任务栈,同时它的模式就会发生改变;

SingleTop
  1. 如果新活动已经位于任务栈的栈顶,那么不会被重建,同时一个方法onNewIntent()会被回调,我们可以通过这个方法的参数取出请求的信息;
SingleTask
  1. 主要流程:

    新活动会查看有没有自己想要的任务栈,如果没有,就会创建新的任务栈,如果有,会查看自己想要的任务栈中有无自己的已经创建过的活动实例,如果有,那么旧活动之前的活动出栈,该旧活动为栈顶,同时会调用onNewIntent()方法,如果没有,那么入栈为栈顶;

  2. 关于前后台:

    1. 前后台有着不同的任务栈;

    2. 当后台的活动被请求,即使没有被重建,后台任务栈会被切换到前台,此时回退列表会发生改变;

      举例:活动ab在前台,cd在后台,如果此时请求启动d,那么按back的结果是abcd;如果请求的是c,那么结果是abc;

  3. 关于新活动如何查看是不是自己想要的任务栈?

    了解这个之前,我们需要了解一个参数

TaskAffinity
  1. 这个参数表示了一个活动所需任务栈的名字;
  2. 默认情况下,活动的任务栈的名字是应用的包名;
  3. 如果指定,不能为包名;
TaskAffinitySingleTask

待启动的活动(SingleTask模式下)会运行在名字和TaskAffinity相同的任务栈中;

TaskAffinityallowTaskReparenting

如果allowTaskReparenting为true:

  1. 如果应用a启动应用b中的活动,那么这个活动会从应用a的任务栈转移到应用b任务栈;

雪雪解释如下:

因为和这个活动会检查任务栈的名字,发现这个活动栈的名字和TaskAffinity不匹配,那么这个时候就会去该活动所在的应用b中去启动它,没有则创建新的任务栈,所以最终这个活动会呆在自己喜欢的任务栈中;

SingleInstance
  1. 是加强版的SingleTask,除了SingleTask的特性外,还
  2. 当活动a启动后,那么会为这个活动去创建新的任务栈,后续的请求不会创建新的活动a的实例,直到任务栈被系统销毁;(永远只有a这一个任务)

Activity中的标志位

什么是标志位
  1. 为一个活动指定启动模式有两种方式,第一种是android:launchMode = "",第二种就是通过在Intent中设置标志位来为活动指定启动模式;

  2. 当两种指定方式都存在而且有冲突时,优先以第二种为准;

  3. 标志位怎么指定?

     Intent intent = new Intent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
  4. 标志位的参数

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    和singleTask的使用别无二致;

    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    和singleTop的使用别无二致;

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    如果启动模式设置为standard,那么会清空该活动以上的所有活动(包括自身),新建一个活动;

    如果启动模式是是singletask,那么清空,复用,调用onNewIntent方法;

    如果启动模式是是singletop,若在栈顶则复用,否则新建

    intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

    标记这个的活动不会出现在历史活动的列表中;

http://www.dtcms.com/a/560755.html

相关文章:

  • AI换脸技术安全指南:3条法律红线与合规实践
  • 【2025-11-01】软件供应链安全日报:最新漏洞预警与投毒预警情报汇总
  • 使用thefuck报错ModuleNotFoundError: No module named ‘distutils‘
  • 算法23.0
  • 怎么做免费的网站推广网站正在建设中 html 模板
  • 鸿蒙Flutter三方库适配指南:10.插件测试
  • 购物车高效开发指南:API与Vuex实战
  • 广州网站建设公司哪家好展厅设计制作
  • 【BFS 解决FloodFill 算法】4. 被围绕的区域(medium)
  • Go channel 的核心概念、操作语义、设计模式和实践要点
  • 现在还可以做夺宝网站怎么让网站被百度搜到
  • 深蓝汽车10月全球销量36792辆 S05销量突破2万辆
  • 四、CSS选择器(续)和三大特性
  • 高职新能源汽车技术专业职业发展指南
  • 初识MySQL:库的操作、数据类型、表的操作
  • AI助力汽车 UI 交互设计
  • 广州市手机网站建设平台有意义网站
  • MySQL到达梦数据库快速替换操作指南
  • Python NumPy广播机制详解:从原理到实战,数组运算的“隐形翅膀”
  • QT背景介绍与环境搭建
  • 【C++:多态】C++多态实现深度剖析:从抽象类约束到虚函数表机制
  • 【软考架构】案例分析-分布式锁
  • 15.5.手机设备信息
  • Mysql基础1
  • 集团网站网页模板网站建设超速云免费
  • HTTPS:现代网站运营的安全基石与价值引擎
  • 老鹰网网站建设外贸是做什么的工作
  • [N_083]基于springboot毕业设计管理系统
  • kotlin学习 lambda编程
  • 如何写好汇报材料经验总结