Android Framework切换主题后应用Activity生命周期变化分析

Android监听运行应用的任务变化包含Activity及Service 本文介绍了两种监听安卓应用运行状态变化的方案:使用IActivityManager和IActivityTaskManager。第一种方案通过注册IProcessObserver回调来监听进程活动变化,但获取包名较复杂。第二种方案从Android 10开始引入,使用registerTaskStackListener回调,能更清晰地获取任务栈变化信息。两种方案都需要引入framework.jar并申请相应权限(SET_ACTIVITY_WATCHER或MANAGE_ACTIVITY_TASKS)。文章通过序列图 阅读详情

零.前言

​   在工作遇到了系统切换主题后,应用页面出现重叠错乱,播放音频的时候出现了点击图标后出现声音停顿1S

后继续播放的问题…

一.生命周期流程

在这里插入图片描述
  此时,Activity经历了销毁到创建,状态保存到恢复状态的过程,不同的手机有一定的差别。

二.源码分析(Android M)

 protected void onSaveInstanceState(Bundle outState) {
        outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState()); // 保存Window
        Parcelable p = mFragments.saveAllState();
        if (p != null) {
            outState.putParcelable(FRAGMENTS_TAG, p);// 保存Fragment
        }
        getApplication().dispatchActivitySaveInstanceState(this, outState);
 }
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
        if (mWindow != null) {
            Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
            if (windowState != null) {
                mWindow.restoreHierarchyState(windowState);// 恢复Window
            }
        }
 }
  protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
        if (mLastNonConfigurationInstances != null) {
            mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
        }
        if (mActivityInfo.parentActivityName != null) {
            if (mActionBar == null) {
                mEnableDefaultActionBarUp = true;
            } else {
                mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
            }
        }
        // 恢复Fragment
        if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                    ? mLastNonConfigurationInstances.fragments : null);
        }
        mFragments.dispatchCreate();
        getApplication().dispatchActivityCreated(this, savedInstanceState);
        if (mVoiceInteractor != null) {
            mVoiceInteractor.attachActivity(this);
        }
        mCalled = true;
  }

三.引起的Fragment页面重叠错乱问题

​    1.原因:在activity onSaveInstanceState执行时activity保存了Window和Fragment的状态

​        onCreate时我们初始化并添加Fragment

​       onCreate和onRestoreInstanceState时恢复了保存的Fragment,综上造成了Fragment
页面重叠错乱

​    2.解决方式:

​     (1).如果在切换主题后没有必要恢复我们应用之前的状态,可以在onSaveInstanceState时直接不保存Fragment状态即可

   static final String FRAGMENTS_TAG = "android:fragments";
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(FRAGMENTS_TAG, null);// 不保存Fragment状态
    }

​ ​      (2).如果需要恢复我们应用之前的状态,可以通过FragmentManager找到保存的Fragment进行复用

    private void showFragment(int index) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        // 找到保存的Fragment进行复用。
        Fragment fragmentByTag = getSupportFragmentManager().findFragmentByTag(TAGS[index]);
        // 执行了onDestory后mFragments数组对象被系统回收了
        if (fragmentByTag != null && mFragments[index] == null) {
            mFragments[index] = (AbstractMainFragment) fragmentByTag;
        }
        if (mFragments[index] == null) {
            if (index == PLAYBACK) {
                mFragments[index] = new PlaybackFragment();
            } else if (index == LIBRARY) {
                mFragments[index] = new LibraryFragment();
            } else {
                mFragments[index] = new MixFragment();
            }
            ft.add(R.id.fl_main, mFragments[index], TAGS[index]);
        }
        for (int i = 0; i < mFragments.length; i++) {
            if (mFragments[i] != null && i != index) {
                ft.hide(mFragments[i]);
            }
        }
        ft.show(mFragments[index]).commitAllowingStateLoss();
        mCurrentTab = index;
    }

四.API说明

​   其实相应方法的API说明介绍的很清楚,要多看API( ̄. ̄)

/**
 * Called when the activity is starting.  This is where most initialization
 * should go: calling {@link #setContentView(int)} to inflate the
 * activity's UI, using {@link #findViewById} to programmatically interact
 * with widgets in the UI, calling
 * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve
 * cursors for data being displayed, etc.
 *
 * <p>You can call {@link #finish} from within this function, in
 * which case onDestroy() will be immediately called without any of the rest
 * of the activity lifecycle ({@link #onStart}, {@link #onResume},
 * {@link #onPause}, etc) executing.
 *
 * <p><em>Derived classes must call through to the super class's
 * implementation of this method.  If they do not, an exception will be
 * thrown.</em></p>
 *
 * @param savedInstanceState If the activity is being re-initialized after
 *     previously being shut down then this Bundle contains the data it most
 *     recently supplied in {@link #onSaveInstanceState}.  <b><i>Note: Otherwise it is null.</i></b>
 *
 * @see #onStart
 * @see #onSaveInstanceState
 * @see #onRestoreInstanceState
 * @see #onPostCreate
 */
protected void onCreate(@Nullable Bundle savedInstanceState) {}
/**
 * Called to retrieve per-instance state from an activity before being killed
 *      * so that the state can be restored in {@link #onCreate} or
 *      * {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method
 *      * will be passed to both).
 *
 * <p>This method is called before an activity may be killed so that when it
 * comes back some time in the future it can restore its state.  For example,
 * if activity B is launched in front of activity A, and at some point activity
 * A is killed to reclaim resources, activity A will have a chance to save the
 * current state of its user interface via this method so that when the user
 * returns to activity A, the state of the user interface can be restored
 * via {@link #onCreate} or {@link #onRestoreInstanceState}.
 *
 * <p>Do not confuse this method with activity lifecycle callbacks such as
 * {@link #onPause}, which is always called when an activity is being placed
 * in the background or on its way to destruction, or {@link #onStop} which
 * is called before destruction.  One example of when {@link #onPause} and
 * {@link #onStop} is called and not this method is when a user navigates back
 * from activity B to activity A: there is no need to call {@link #onSaveInstanceState}
 * on B because that particular instance will never be restored, so the
 * system avoids calling it.  An example when {@link #onPause} is called and
 * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A:
 * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't
 * killed during the lifetime of B since the state of the user interface of
 * A will stay intact.
 *
 * <p>The default implementation takes care of most of the UI per-instance
 * state for you by calling {@link android.view.View#onSaveInstanceState()} on each
 * view in the hierarchy that has an id, and by saving the id of the currently
 * focused view (all of which is restored by the default implementation of
 * {@link #onRestoreInstanceState}).  If you override this method to save additional
 * information not captured by each individual view, you will likely want to
 * call through to the default implementation, otherwise be prepared to save
 * all of the state of each view yourself.
 *
 * <p>If called, this method will occur before {@link #onStop}.  There are
 * no guarantees about whether it will occur before or after {@link #onPause}.
 *
 * @param outState Bundle in which to place your saved state.
 *
 * @see #onCreate
 * @see #onRestoreInstanceState
 * @see #onPause
 */
protected void onSaveInstanceState(Bundle outState) {}
/**
 * This method is called after {@link #onStart} when the activity is
 * being re-initialized from a previously saved state, given here in
 * <var>savedInstanceState</var>.  Most implementations will simply use {@link #onCreate}
 * to restore their state, but it is sometimes convenient to do it here
 * after all of the initialization has been done or to allow subclasses to
 * decide whether to use your default implementation.  The default
 * implementation of this method performs a restore of any view state that
 * had previously been frozen by {@link #onSaveInstanceState}.
 *
 * <p>This method is called between {@link #onStart} and
 * {@link #onPostCreate}.
 *
 * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
 *
 * @see #onCreate
 * @see #onPostCreate
 * @see #onResume
 * @see #onSaveInstanceState
 */
protected void onRestoreInstanceState(Bundle savedInstanceState) { }
Android Framework学习一:系统框架、启动过程 Zygote 进程是 Android 系统中由 init 进程启动的第一个 Java 进程,它运行着一个 Java 虚拟机(JVM)实例,并且预加载了大量的系统资源和类,能够快速创建新的应用程序进程和部分系统服务进程。zygote是由init进程fork出来的,在Android中,DVM和ART、应用程序进程以及运行系统的关键服务的SyetemService进程都是由Zygote进程来创建的,所以称之为孵化器。init 进程主要通过解析配置文件来确定要执行的操作和启动的服务。init是用户空间的鼻祖。 阅读详情

相关推荐

Android随笔-Activity

本文系统介绍了Android开发中的Activity组件。首先指出Activity是Android四大组件中唯一负责用户交互的组件,解释了其继承体系和核心职责(UI容器、生命周期管理、任务栈管理等)。重点剖析了Activity生命周期的7个核心回调方法:onCreate()、onStart()、onResume()、onPause()、onStop()、onRestart()和onDestroy(),详细说明了每个方法的触发时机、典型操作和调用次数,并通过生命周期流程图直观展示了状态转换关系。最后定义了Ac

古典码 862

android夜间模式下activity横竖屏切换重走生命周期问题

最近在弄夜间模式的时候遇到activity在夜间模式下,activity会重走生命周期,而正常模式不会重走。1.首先夜间模式使用的是https://blog.youkuaiyun.com/qq_20521573/article/details/76222085博客中的实现方式,这里再把使用中细节地方说一下,如果实在Application中填写了主题,那么activity中不必再写相关切换主题的代码,activ...

muscle_sunny的博客 1808

Android系统架构之Android Framework

这些API和工具为开发者提供了构建各种类型Android应用的能力,从简单的个人应用到复杂的企业级解决方案。通过这些API,开发者可以轻松实现用户界面设计、数据处理、网络通信、多媒体处理等多种功能。Android Framework提供了广泛的API和工具,这些API和工具覆盖了从基础的UI组件到高级的系统服务。

bai915290475的博客 631

Android打造丝滑的Activity recreate重建(主题切换)过渡动画

Activity recreate重建(主题切换)过渡动画实现 当应用程序支持多种语言或主题时,切换语言或主题通常需要重新启动 Activity 以重新加载配置。虽然 recreate 是一种常用的重建 Activity 方法,但它不支持像在 Activity 之间切换时那样使用过渡动画。特别是在切换 浅色/深色 主题时,由于缺乏过渡动画而显得很生硬。为了提升改善这一点,只能自己实现过渡动画以提供更流畅的用户体验。

qq_45925230的博客 3432

Android Framework深度探秘:应用生命周期回调分发机制全解析

底层架构如同大厦筋骨,掌控核心机理方能游刃有余。

郑伟强dev的专栏 46

深入解析Android应用生命周期回调分发机制:从原理到实战

本文系统讲解了Android应用生命周期回调分发机制,涵盖核心原理、实现细节和开发实践。主要内容包括:1. 应用生命周期概述及回调分发的重要性;2. 基于观察者模式的设计原理和分层架构;3. 典型场景的工作流程解析及代码示例;4. 常见问题与最佳实践,如内存管理和性能优化;5. 针对性面试问题与深度解析。文章强调合理利用该机制对应用性能、稳定性和用户体验的关键作用,为开发者提供从理论到实践的全面指导。

郑伟强dev的专栏 127

Android设备切换系统模式时导致Activity重建

当添加了android:configChanges="uiMode"后,系统将不会简单的销毁重建Activity来响应UI模式(如模式切换)系统将调用Activity的onConfigruationChanged(Configuration newConfig)方法,在方法中你可以处理与UI模式相关的任何更改,比如更新UI的颜色方案。如果你的应用依赖于某些特定的配置,或者配置变化会导致复杂的UI调整,那么确保你在onConfigurationChanged方法中实现了这些逻辑是非常重要的。

m0_63307502的博客 1957

Fragment实现Android底部导航切换

简单来说,Fragment代表了Activity的一个模块片段,它拥有自己的生命周期,并且可以接收自己的输入事件,同时它还可以在运行时添加到或者从Activity中移除。需要注意的是,Fragment依赖于Activity,不能独立存在。它的设计允许在不同的Activity中复用同一段用户界面代码,从而减少重复工作。Fragment需要一个布局文件来定义其界面。这个布局文件通常位于项目的res/layout目录下。

weixin_36238982的博客 368

Activity的重建(recreate)与恢复

关于Activity的重建我们可以从以下三个方面去了解: Activity会出现重建的三种情况: 1. 系统内存不足:android系统会杀死一个进程,在系统需要释放内存的时候,而位于进程内的activity就会被销毁。在用户重新回到这个Activity的时候,这个Activity 就会被重建。 2. Configuration Change(Activity横竖屏切换,进入多窗口模式):在...

mypotatolove的专栏 1万+

Supermind量化实战:我如何给双均线策略加上“止损”和“仓位管理”,让回测收益更稳健

本文详细介绍了如何在Supermind平台上为双均线策略添加止损和仓位管理模块,以提升量化交易的稳健性。通过Python实现动态止损和智能仓位管理,策略的年化收益率从12.3%提升至15.8%,最大回撤从58.7%降至22.4%,Sharpe比率显著提高。这些实战技巧适用于量化交易爱好者,帮助他们在黑天鹅行情中保持收益稳定。

weixin_42567752的博客 362

VESC电调高级调参指南:电机校准与性能优化实战解析

本文详细解析了VESC电调的高级调参方法,包括电机校准与性能优化实战技巧。从基础参数设置到高级机械参数优化,再到动态性能调优,提供了全面的调参指南。特别针对电机类型、功率设置、电池参数配置等关键环节给出实用建议,帮助用户充分发挥VESC电调的性能潜力。

weixin_30772105的博客 196

AndHook实战案例:Hook Activity生命周期方法的最佳实践

AndHook是一款功能强大的Android动态插桩框架,能够帮助开发者在不修改目标应用源代码的情况下,对应用程序进行调试、分析和功能增强。本文将通过实战案例,详细介绍如何使用AndHook框架来Hook Activity的生命周期方法,掌握这一技能可以让你轻松实现对Android应用界面行为的监控与控制。 ## AndHook框架简介 AndHook框架提供了简洁易用的API,支持对Java

gitblog_00017的博客 871

ADS入门学习笔记——低噪声放大器(2)

1、输入匹配网络; 2、输出匹配网络;

weixin_42126696的博客 4990

Activity

1.Activty A B间切换,生命周期的7个方法 执行A.startAvtivity(B),A.finish() 代码响应执行顺序:A.onPause(),B.onCreate(),B.onStart(),B.onResume(),A.onStop(),A.onDestroy().   执行A.startAvtivity(B) 代码响应执行顺序:A.onPause(),B.onCreat

1795

机器学习实战26-一种基于LightGBM的股市涨跌预测系统与代码实现过程

在全球经济一体化的背景下,股市作为经济活动的晴雨表,其波动与预测对于投资者、金融机构乃至国家政策制定者而言至关重要。随着金融市场的日益复杂化与信息量的爆炸式增长,股市分析不再仅限于基本面和技术面的传统研究,而是迫切需要更加精准、高效及智能化的方法来捕捉市场动态,以辅助决策制定。模型评估是确保LightGBM股市预测系统准确性和稳定性不可或缺的一环。通过综合运用多种评估指标、科学的验证方法以及深入的性能分析,我们不仅能够全面理解模型的能力和限制,还能为持续优化模型、提升预测准确性奠定坚实基础。

微学AI的博客 2327

YOLO11改进 | 主干网络 | 添加Hyper-YOLO的MANet混合聚合网络

本文详细介绍了在YOLO11目标检测模型中替换C3k2模块为MANet的具体实现方法。文章首先讲解MANet模块的原理,然后分步骤指导如何在YOLO11中添加该模块,包括代码修改、文件配置和模型注册等关键环节。通过实验对比,改进后的YOLO11_MANet模型在保持8.8GFLOPs计算量的同时,参数数量达到3,820,272,网络层数增加到343层。文章还提供了完整的代码实现和网络结构图,并建议结合其他注意力机制或损失函数进一步提升检测效果。最后推荐了相关的深度学习专栏,包含更多YOLO系列改进方法。

kay_545 658

Activity生命周期在Framework层的体现

<br /> resumeTopActivityLocked这个函数完成了Activity生命周期状态机的跳转,具体的执行过程可以看相册Android目录下的流程图。下面是关于Activity切换时候的状态变化Step1:  First Activity launch: 系统自动会调用,调用时机如下: •onCreate 设置布局文件 绑定监听器等等 •onstart Activity能被我们看到时调用 •onResume Activity能够获得用户焦点的时候会被调用 Step2:Second Acti

hitxiaotao的专栏 1031

Ubuntu 系统下安装 OpenClaw(原 Clawdbot)的详细指南

Ubuntu 系统下安装 OpenClaw(原 Clawdbot)的详细指南

Science prince的博客 3535

Android-Plugin-Framework Fragment内嵌:插件UI组件在宿主Activity中的完美融合

Android-Plugin-Framework是一个功能强大的Android插件框架,支持免安装运行插件APK,实现了独立插件和非独立插件的灵活部署。本文将重点介绍如何通过该框架实现Fragment内嵌,让插件UI组件在宿主Activity中实现无缝融合,为应用开发带来全新的可能性。 ## 什么是Fragment内嵌? Fragment作为Android开发中的重要UI组件,具有独立的生命周

gitblog_00077的博客 495

Altium Designer(AD)仿真实验操作指南

1:运行仿真2:设置仿真3:放置电源模块4:放置器件模块5:探针。

XU157303764的博客 8897

【01】总目录——软件设计师50讲通关地图|从零基础到工程师职称

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏的01篇总目录,系统梳理了50篇博文的完整架构与核心逻辑。专栏覆盖软考软件设计师(中级)全部考点,分为导学规划、基础知识、设计模式、下午题专项、算法实战、冲刺模拟、收官进阶七大模块,既兼顾上午题75道单选题的理论攻坚,也聚焦下午题案例分析的解题能力提升。每篇博文均包含考点精讲、真题解析、实战技巧与速记方法,配套可运行代码、解题模板及备考资源。无论你是零基础转行、在校学生还是在职程序员,都能通过这份学习地图明确进度、精准定位薄弱环节,高效搭建知识体系

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1279

Android 高级工程师面试参考答案:Framework、生命周期、View 与 Binder

本文探讨了Android开发中的核心机制与常见问题,主要包括:1)Activity启动流程的关键环节,强调系统服务调度和进程创建;2)onSaveInstanceState的适用场景与局限性;3)Handler/Looper消息循环模型的工作原理;4)ANR的深层原因与排查方法;5)事件分发机制与滑动冲突解决;6)View绘制流程的性能优化要点。文章着重指出,高级开发者应理解系统链路而非仅记忆类名,并提供了应对面试追问的实用回答策略。

帅次的博客 1140

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

android的 framework 有哪些知识点和应用场景

【代码】android的 framework 有哪些知识点和应用场景。

weixin_42283818的博客 677

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Android 应用高级面试:Activity 近1年高频追问 22 题

本篇聚焦 Activity 生命周期、启动模式与 Task 栈,面向应用高级面试备战者。覆盖基础 8 题、进阶 7 题、核心 7 题,从回调时序、launchMode 到配置变更与 ATMS 启动链路。参考回答讲清机制;工程落地见追问。读完可系统复述 Activity 真高频问答,并口述启动链路与状态恢复

帅次的博客 2280

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

android_transition_framework

职责:代表一个逻辑上的窗口状态转换,跟踪从旧状态到新状态的所有变化。

weixin_42143160的博客 386

安卓已死?熬夜肝完这份Framework笔记,真香!

Android没凉,只是比以前难混了 7年前Android异军突起,成了新的万亿级市场,无数掘金人涌入,期待可以一展拳脚。 那时候大环境下的手游圈,只要你能有个可以运行的连连看就能找到工作,走上赛道被浪潮推着前进,这个行业不可谓不光明。 2020了,浪潮速度放缓,漫天飞舞着唱衰Android的讯息,“凉凉”是最多的字眼。 但放心,Android真的没凉! Android入门相对简单,初级Android很多很多,趋近饱和,你随意打开一个招聘app就能很直观的判断出来,现在Android准入的条件越来越高了。

左夜天 256
上一篇: Ubuntu 开机进不去桌面问题记录
下一篇: Android 自定义均衡器View
dongpingwang
博客等级 码龄9年 101粉丝 121原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值