范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Google官方梳理,Android多返回栈技术详解

  用户通过系统返回按钮导航回去的一组页面,在开发中被称为返回栈 (back stack)。多返回栈即一堆 "返回栈",对多返回栈的支持是在 Navigation 2.4.0-alpha01  和 Fragment 1.4.0-alpha01  中开始的。本文将为你展开多返回栈的技术详解。
  系统返回按钮的乐趣
  无论你在使用 Android 全新的 手势导航  还是传统的导航栏,用户的 "返回" 操作是 Android 用户体验中关键的一环,把握好返回功能的设计可以使应用更加贴近整个生态系统。
  在最简单的应用场景中,系统返回按钮仅仅 finish 你的 Activity。在过去你可能需要覆写 Activity 的 onBackPressed() 方法来自定义返回操作,而在 2021 年你无需再这样操作。我们已经在 OnBackPressedDispatcher  中提供了 针对自定义返回导航的 API 。实际上这与 FragmentManager  和 NavController  中 已经 添加的 API 相同。
  这意味着当你使用 Fragments 或 Navigation 时,它们会通过 来确保你调用了它们返回栈的 API,系统的返回按钮会将你推入返回栈的页面逐层返回。
  多返回栈不会改变这个基本逻辑。系统的返回按钮仍然是一个单向指令 —— "返回"。这对多返回栈 API 的实现机制有深远影响。
  Fragment 中的多返回栈
  在 surface 层级,对于 多返回栈的支持  貌似很直接,但其实需要额外解释一下 "Fragment 返回栈" 到底是什么。FragmentManager 的返回栈其实包含的不是 Fragment,而是由 Fragment 事务组成的。更准确地说,是由那些调用了 addToBackStack(String name)  API 的事务组成的。
  这就意味着当你调用 commit()  提交了一个调用过 addToBackStack()  方法的 Fragment 事务时,FragmentManager  会执行所有你在事务中所指定的操作 (比如 替换操作 ),从而将每个 Fragment 转换为预期的状态。然后 会将该事务作为它返回栈的一部分。
  当你调用 popBackStack()  方法时 (无论是直接调用,还是通过系统返回键以 内部机制调用),Fragment 返回栈的最上层事务会从栈中弹出 -- 比如新添加的 Fragment 会被移除,隐藏的 Fragment 会显示。这会使得 恢复到最初提交 Fragment 事务之前的状态。
  也就是说 变成了销毁操作: 任何已添加的 Fragment 在事务被弹出的时候都会丢失它的状态。换言之,你会失去视图的状态,任何所保存的实例状态 (Saved Instance State),并且任何绑定到该 Fragment 的 ViewModel 实例都会被清除。这也是该 API 和新的saveBackStack()  方法之间的主要区别。 可以实现弹出事务所实现的返回效果,此外它还可以确保视图状态、已保存的实例状态,以及 ViewModel 实例能够在销毁时被保存。这使得 restoreBackStack()  API 后续可以通过已保存的状态重建这些事务和它们的 Fragment,并且高效 "重现" 已保存的全部细节。太神奇了!
  而实现这个目的必须要解决大量技术上的问题。
  排除 Fragment 在技术上的障碍
  虽然 Fragment 总是会保存 Fragment 的视图状态 ,但是 Fragment 的 onSaveInstanceState() 方法只有在 Activity 的 onSaveInstanceState() 被调用时才会被调用。为了能够保证调用 saveBackStack() 时 SavedInstanceState 会被保存,我们 还 需要在 Fragment 生命周期切换 的正确时机注入对 onSaveInstanceState() 的调用。我们不能调用得太早 (你的 Fragment 不应该在 STARTED 状态下保存状态),也不能调用得太晚 (你需要在 Fragment 被销毁之前保存状态)。
  这样的前提条件就开启了需要 解决 FragmentManager 转换到对应状态的问题 ,以此来保障有一个地方能够将 Fragment 转换为所需状态,并且处理可重入行为和 Fragment 内部的状态转换。
  在 Fragment 的重构工作进行了 6 个月,进行了 35 次修改时,发现 Postponed Fragment 功能已经严重损坏 ,这一问题使得被推迟的事务处于一个中间状态 —— 既没有被提交也并不是未被提交。之后的 65 个修改和 5 个月的时间里,我们几乎重写了 管理状态、延迟状态切换和动画的内部代码,具体请参见我们之前的文章《全新的 Fragment: 使用新的状态管理器 》。
  Fragment 中值得期待的地方
  随着技术问题的逐步解决,包括更加可靠和更易理解的 ,我们新增加了两个 API: 和 。
  如果你不使用这些新增 API,则一切照旧: 单个 返回栈和之前的功能相同。现有的 保持不变 —— 你可以将 name  赋值为 null 或者任意 。然而,当你使用多返回栈时, 的作用就非常重要了: 在你调用 和之后的 方法时,它将作为 Fragment 事务的唯一的 key。
  举个例子,会更容易理解。比如你已经添加了一个初始的 Fragment 到 Activity,然后提交了两个事务,每个事务中包含一个单独的 replace 操作:// 这是用户看到的初始的 Fragment fragmentManager.commit { setReorderingAllowed(true) replace(R.id.fragment_container) } // 然后,响应用户操作,我们在返回栈中增加了两个事务 fragmentManager.commit { setReorderingAllowed(true) replace(R.id.) addToBackStack("profile") } fragmentManager.commit { setReorderingAllowed(true) replace(R.id.) addToBackStack("edit_profile") }
  也就是说我们的 FragmentManager 会变成这样:
  提交三次之后的 FragmentManager 的状态
  比如说我们希望将 profile 页换出返回栈,然后切换到通知 Fragment。这就需要调用 并且紧跟一个新的事务:fragmentManager.saveBackStack("profile") fragmentManager.commit { setReorderingAllowed(true) replace(R.id.) addToBackStack("notifications") }
  现在我们添加 ProfileFragment  的事务和添加 EditProfileFragment  的事务都保存在 "profile" 关键字下。这些 Fragment 已经完全将状态保存,并且 会随同事务状态一起保持它们的状态。很重要的一点: 这些 Fragment 的实例并不在内存中或者在 中 —— 存在的仅仅只有状态 (以及任何以 ViewModel  实例形式存在的非配置状态)。
  我们保存 profile 返回栈并且添加一个新的 commit 后的 FragmentManager 状态
  替换回来非常简单: 我们可以在 事务中同样调用 saveBackStack() 操作,然后调用 :fragmentManager.saveBackStack("notifications") fragmentManager.restoreBackStack("profile")
  这两个堆栈项高效地交换了位置:
  交换堆栈项后的 FragmentManager 状态
  维持一个单独且活跃的返回栈并且将事务在其中交换,这保证了当返回按钮被点击时, 和系统的其他部分可以保持一致的响应。实际上,整个逻辑并未改变,同之前一样,仍然弹出 Fragment 返回栈的最后一个事务。
  这些 API 都特意按照最小化设计,尽管它们会产生潜在的影响。这使得开发者可以基于这些接口设计自己的结构,而无需通过任何非常规的方式保存 Fragment 的视图状态、已保存的实例状态、非配置的状态。
  当然了,如果你不希望在这些 API 之上构建你的框架,那么可以使用我们所提供的框架进行开发。
  使用 Navigation 将多返回栈适配到任意屏幕类型
  Navigation Component  最初 是作为通用运行时组件进行开发的,其中不涉及 View、Fragment、Composable 或者其他屏幕显示相关类型及你可能会在 Activity 中实现的 "目的地界面"。然而,NavHost 接口  的实现中需要考虑这些内容,通过它添加一个或者多个 Navigator  实例时,这些实例 确实 清楚如何与特定类型的目的地进行交互。
  这也就意味着与 Fragment 的交互逻辑全部封装在了 navigation-fragment  开发库和它其中的 FragmentNavigator  与 DialogFragmentNavigator  中。类似的,与 Composable 的交互逻辑被封装在完全独立的 navigation-compose  开发库和它的 ComposeNavigator  中。这里的抽象设计意味着如果你希望仅仅通过 Composable 构建你的应用,那么当你使用 Navigation Compose 时无需任何涉及到 Fragment 的依赖。
  该级别的分离意味着 Navigation 中有两个层次来实现多返回栈:保存独立的 NavBackStackEntry   实例状态,这些实例组成了 NavController  返回栈。这是属于 的职责。保存 Navigator 针对每个 的特定状态 (比如与 目的地相关联的 Fragment)。这是属于 Navigator  的职责。
  仍需特别注意那些 尚未 更新的 ,它们无法支持保存自身状态。底层的 API 已经整体重写来支持状态保存 (你需要覆写新增的 navigate()  和 API 的重载方法,而不是覆写之前的版本),即使 并未更新, 仍会保存 的状态 (在 Jetpack 世界中向后兼容是非常重要的)。
  备注: 通过绑定  TestNavigatorState  使其成为一个 mini-NavController  可以实现在新的 API 上更轻松、独立地测试你自定义的 。
  如果你仅仅在应用中使用 Navigation,那么 这个层面更多的是实现细节,而不是你需要直接与之交互的内容。可以这么说,我们已经完成了将 和 迁移到新的 Navigator API 的工作,使其能够正确地保存和恢复它们的状态,在这个层面上你无需再做任何额外工作。
  在 Navigation 中启用多返回栈
  如果你正在使用 NavigationUI ,它是用于连接你的 到 Material 视图组件的一系列专用助手,你会发现对于菜单项、BottomNavigationView  (现在叫 NavigationRailView ) 和 NavigationView ,多返回栈是 默认启用 的。这就意味着结合 和 navigation-ui  使用就可以。
  NavigationUI  API 是基于 Navigation 的其他公共 API 构建的,确保你可以准确地为自定义组件构建你自己的版本。保证你可以构建所需的自定义组件。启用保存和恢复返回栈的 API 也不例外,在 Navigation XML 中通过 NavOptions  上的新 API,也就是 navOptions  Kotlin DSL,以及 的重载方法可以帮助你指定 pop 操作保存状态或者指定 navigate 操作来恢复之前已保存的状态。
  比如,在 Compose 中,任何全局的导航模式 (无论是底部导航栏、导航边栏、抽屉式导航栏或者任何你能想到的形式) 都可以使用我们在与 底部导航栏集成  所介绍的相同的技术,并且结合 saveState  和 restoreState  属性一起调用 :onClick = { navController.navigate(screen.route) { // 当用户选择子项时在返回栈中弹出到导航图中的起始目的地 // 来避免太过臃肿的目的地堆栈 popUpTo(navController.graph.findStartDestination().id) { saveState = true }  // 当重复选择相同项时避免相同目的地的多重拷贝 launchSingleTop = true // 当重复选择之前已经选择的项时恢复状态 restoreState = true } }
  保存状态,锁定用户
  对用户来说,最令人沮丧的事情之一便是丢失之前的状态。这也是为什么 Fragment 用一整页来讲解 保存与 Fragment 相关的状态 ,而且也是我非常乐于更新每个层级来支持多返回栈的原因之一:Fragments (比如完全不使用 Navigation Component): 通过使用新的 API,也就是 saveBackStack  和 restoreBackStack 。核心的 Navigation 运行时: 添加可选的新的 方法用于 (恢复状态) 和 (保存状态) 以及新的 popBackStack () 的重载方法,它同样可以传入一个布尔型的 参数 (默认是 false)。通过 Fragment 实现 Navigation: 现在利用新的 NavigatorAPI ,通过使用 Navigation 运行时 API 将 Navigation 运行时 API 转换为 Fragment API。: 每当它们弹出返回栈时,onNavDestinationSelected ()、NavigationBarView.setupWithNavController()  和 NavigationView.setupWithNavController()  现在默认使用 restoreState 和 saveState 这两个新的 NavOption。也就意味着 当升级到 Navigation 2.4.0-alpha01 或者更高版本后,任何使用 NavigationUI API 的应用无需修改代码即可实现多返回栈。
  如果你希望了解 更多使用该 API 的示例 ,请参考 NavigationAdvancedSample  (它是最新更新的,且不包含任何用于支持多返回栈的 NavigationExtensions  代码)。
  对于 Navigation Compose 的示例 ,请参考 Tivi。
  如果你遇到任何问题,请使用官方的问题追踪页面提交关于 Fragment  或者 Navigation  的 bug,我们会尽快处理。
  本文由码农老K原创,欢迎关注,我们一起长知识!

五一能去哪儿玩?李兰娟院士这么说今年的五一是个长假。从5月1日到5月5日,总共放假5天。每年的五月,正是阳光明媚的好时候,也是出行游玩的高峰时段。可是因为疫情的影响,今年情况比较特殊。今年还能出去玩吗,或者说还能一加首款降噪耳机BudsPro很强吗?这些专业媒体的评价很中肯一加作为一个专注于高端旗舰的品牌,不仅是在国内推出的手机备受关注,推出的其他数码产品也是受到了非常多用户的注视。最近,一加首款降噪真无线耳机OnePlusBudsPro正式登场,集通过灯泡都可以窃听,你害怕了没?近日,来自以色列的研究团队公开展示了一项窃听技术。而且,通过灯泡就可以了。原理简单,那就是咱们中学都学过的振动。在房间里说话时,发出的声音会在灯泡表面产生细微的振动。而这些振动则会人民需要什么就造什么,五菱汽车也要卖螺蛳粉?这两天,五菱汽车又弄出来了个新闻。因为五菱汽车,要造螺蛳粉了。其实早在今年3月份的时候,网上就流传出一张印有五菱牌的螺蛳粉包装图。而对此,当时五菱汽车相关负责人也没有否认,仅对外表不止10亿色!FindX3发布会回顾,精华都在这了经过一波紧锣密鼓的宣传后,OPPOFindX3系列终于在3月11日跟大家正式见面了,所带来的配置也与之前在网上爆料的消息基本一致,不可能的曲面艺术设计全链路10bit色彩引擎,10就凭拍照稳颜值高,vivoX60Pro即成春天旅游神器虽然如今不少地方温度还不算高,但是如今的确是一个不错的春游季节,鲜花已经盛开,选择阳光明媚的一天出门踏青足以让人心情舒畅。而在出门游玩的过程中,带着vivoX60Pro去拍照就是一性能续航影音全面升级,无短板水桶旗舰新机,明日正式登场小米10Pro自上市以来,以优质的性能和优惠的价格掳获了一批网友的心,作为它的下一任接棒员全新的小米10S明日正式亮相,不仅性能续航以及散热囊括了所有的旗舰体验,而且小米延续了为用RedmiK40系列备货诚意十足,将于3月8日开启二轮发售3月4日零点,RedmiK40系列全网开启首销,预售阶段3秒售空的热烈反响,早已预见此系列的火爆程度,但首销5分钟销量突破30万台的优秀成绩依然带来了很多惊喜,受欢迎程度可想而知,vivoS9首创双柔光前置,轻松照亮黑夜里的颜值众所周知,vivoS系列一直都是主打轻薄自拍机型,而颜值在线这点也让它收获了一大批忠实的年轻用户群体,最近刚发布的新机vivoS9也不例外,性能强劲颜值担当自拍出色等特点成为了它的FindX3还未发布就获好彩头,OPPO斩获国内市场第一日前,知名研究机构Counterpoint发布了2021年1月份最新的国内手机销量报告,其中OPPO智能手机的出货量以26的同比增长,环比增长更是达到了33,最终实现21的市场份额Redmi游戏手机命名正式确定,外观条件有游戏手机样子了Redmi游戏手机终于要来了!而今天Redmi官微也正式官宣了Redmi游戏手机的命名和机型的部分渲染图,从RedmiK40游戏增强版的命名可以看出,此款游戏手机将归属于K40产品
独家小红书组织架构调整,社区部和电商部将合并新言财经从多个信源独家获悉,小红书于近日进行了组织架构调整,原有的社区部和电商部将合并成新的社区部门。此外,有消息称,小红书COO柯南要带电商业务。新言财经就此事向小红书方面求证,付费直播已来,如何才能撬开用户钱包?现在,各大自媒体平台正在相继推出付费直播节目。1月24下午,微信视频号在腾讯NBA上线首个付费直播间,一些喜欢看篮球赛的观众在微信视频平台收看节目就需要付费才能观看。笔者不是球迷,新能源巨头全球抢矿,争夺话语权过去的2021年,中国新能源汽车销量站上了300万辆的高位,一举奠定这个行业的发展根基。一众电动车企和电池生产商,也超越了金融地产互联网大佬,站上了C位。欲戴其冠必承其重。随着需求快看小红书组织架构调整社区部和电商部合并记者佘晓晨编辑1月25日,据新言财经报道,小红书于近日进行了组织架构调整,原有的社区部和电商部将合并成新的社区部门。此外,有消息称,小红书COO柯南将负责电商业务。对此,小红书方面Hi大家好我是退坡Hi大家好我是退坡1。有人问,新能源退坡30是什么意思?就是guojia补贴政策减少,换言之就是新能源的补贴少了那么你买这台车的到手价就高了。2。关我什么事?新能源全系涨价,只要你美媒评出消费电子展最酷新品韶音OpenRunPro骨传导耳机据美国新闻周刊网站1月5日报道,今年的消费电子展(CES)延续了为接下来的一年里我们可以期待的各种技术定下基调的传统。新闻周刊刊文介绍了2022年美国消费电子展25款最酷的新产品装腾讯2021年近70人因触犯腾讯高压线被辞退中新财经1月25日电据阳光腾讯25日消息,2021年全年,腾讯反舞弊调查部共发现并查处触犯腾讯高压线案件50余起,近70人因触犯腾讯高压线被辞退,10余人因涉嫌犯罪被移送公安机关处太阳能光伏发电应用与前景太阳能光伏发电概述太阳能是首屈一指的绿色能源,太阳能每秒钟到达地面的能量高达8105kW,假如把到达地球表面0。1的太阳能转为电能,转变率为5,每年发电量可达5。61012kWh,小米新款骁龙8旗舰机爆料MIXFOLD2配备8英寸2。5K屏IT之家1月24日消息,今日微博博主数码闲聊站再次对小米未来的新机进行爆料。他表示,小米品牌现在进入排期规划的还有两台骁龙8Gen1平台高分屏旗舰一个采用6。7英寸2K120HzL线上会展迅猛发展,项目展览馆也有这类改变伴随着互联网大数据等科技形式的进步,很多东西也利用这类形式,造成着突飞猛进的改变。项目的开办策略开办形式在持续产生变化,但项目展览馆的进步貌似下降了。怎样可以让项目展览馆为项目整合新材料可在室温下进行量子翻转据最新一期英国自然通讯报道,美国密歇根大学开发出一种半导体材料,可在室温条件下实现从导体到绝缘体的量子翻转,有助于开发新一代量子设备和超高效电子设备。研究人员在只有一个原子厚的二维