barriers / 阅读 / 详情

电信 领航者Navigator1-2 超级用户账号密码是多少?

2023-07-14 22:59:17
共2条回复
南yi

  商务领航Navigator2-1初始用户名和密码:

  用户名:useradmin密码是:admin!@#$%^

  “商务领航”是中国电信推出的面向所有企业客户的、旨在服务于企业信息化的全新客户品牌。商务领航是中国电信战略转型的重要业务。

  其主要商业模式发源于上海电信2003年创办并成功运营2年多的“理想商务”中小企业信息化公共服务平台业务。

clou

telecomadmin

nE7jA%5m

那就是被电信修改了,要拆机破解。

相关推荐

AD13中的navigator在哪

AD13的navigator可以在右下角,点击design compiler,就有navigator选项,见下图:
2023-07-14 21:31:421

navigator如何使用?

可以自定义,把navigator调出,用鼠标把图标拖拽到navigator上就可以了。直接把navigator上的图标拖拽到别处即删除。最多8个图标。
2023-07-14 21:31:551

浏览器软件Navigator是哪个公司的产品?

rdyfdrres thzdfhsfh
2023-07-14 21:32:042

点击脚本错误navigator未定义

1.右击IE图标——属性——高级——选中“禁用脚本调试”,取消“显示每个脚本错误的通知”;2、右击我的电脑图标——属性——高级——错误报告——选中“禁用错误报告”。
2023-07-14 21:32:121

微信小程序navigator怎么实现页面跳转

您好!很高兴能为您解答, 微信小程序 跳转页面 小程序页面有2种跳转,可以在wxml页面或者js中: 1,在wxml页面中: ? 1 2 3 跳转到新页面 在当前页打开 切换到首页Tab 2,在js页面中: 【注意】此处注意两个关键词 “应用内的页面” 和 “tabBar页
2023-07-14 21:32:211

如何安装Navigator

不知道你是需要Driver Navigator(驱动程序管理软件) 还是SyncNavigator数据库同步软件的安装说明。Driver Navigator(驱动程序管理软件)http://www.ddooo.com/softdown/72517.htmDriver Navigator安装破解方法:1、首先运行压缩包中的安装程序进行安装原版程序!2、安装完成后记得先不要运行程序!3、复制压缩包中的补丁程序到安装目录!4、运行补丁程序对主程序打补丁即可。5、切记,打补丁时一定要关闭(即所安装程序的主程序).否则会失败的!
2023-07-14 21:32:281

navigator对象的什么属性,判断出浏览器的内核信息

navigator.userAgent可以判断完整的浏览器信息包括操作系统、浏览器内核及版本等
2023-07-14 21:32:351

现在还支持navigator.geolocation定位吗?

如果你的代码不能正常获取地理位置,可能是由于以下几点原因造成的:浏览器不支持地理位置获取功能。目前,只有主流浏览器都支持地理位置获取功能。如果你使用的是一些过时或不常用的浏览器,可能会导致获取地理位置失败。用户没有授权浏览器获取地理位置。这种情况可能是因为浏览器没有开启定位功能,或者用户拒绝了浏览器的定位请求。当你第一次使用浏览器获取地理位置时,会弹出一个对话框,询问用户是否授权浏览器获取地理位置。如果用户没有授权,你的代码将无法获取地理位置。可以在调用getCurrentPosition()方法之前,先通过navigator.geolocation.permissions.query()方法来检查定位功能是否开启,并在回调函数中判断用户是否同意定位请求。请点击输入图片描述同时,在使用getCurrentPosition()方法时,也可以传递一些配置项,如指定获取位置信息的超时时间、是否持续获取位置信息、是否允许缓存位置信息地理位置获取超时。在你的代码中,你可以使用 options 参数来设置获取地理位置的超时时间。
2023-07-14 21:32:421

中国电信商务领航定制无线路由器(Navigator2-1) 登陆帐号和密码?

useradmin密码是:admin!@#$%^telecomadmin的密码是:nE7jE%5m不过这些密码输错3次就无效了,要恢复出厂设置。点击↓官方网址获取更多服务 客服324为你解答。
2023-07-14 21:32:573

如何修改游览器的navigator.platform属性

JS获取浏览器信息 浏览器代码名称:navigator.appCodeName 浏览器名称:navigator.appName 浏览器版本号:navigator.appVersion 对Java的支持:navigator.javaEnabled() MIME类型(数组):navigator.mimeTypes 系统平台:navigator.platform 插件(数组):navigator.plugins 用户代理:navigator.userAgent
2023-07-14 21:33:061

如何修改游览器的navigator.platform属性

右击ie浏览器,选择属性,然后点击安全或打开浏览器—选择“工具”—Internet选项—点击安全。然后选择自定义级别,就会看到有关级别设置
2023-07-14 21:33:261

在html5中使用navigator.getUserMedia打开相机,要怎样进行关闭

大概的写了下 拍照结果: $(document).ready(init); function init() {//为了便于使用这个接口,先做一下兼容性处理navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; //Google .
2023-07-14 21:33:341

navigator.userAgent.toLowerCase() 什么意思?

呵呵,这个就不会啦! 领航员, 驾驶员,航海家 使用者中介 lowercase是小写字母的意思。你看着自己组合吧,呵呵。好像不是一句话啊。
2023-07-14 21:34:113

DXP里面navigator关掉了怎么打开

在DXP的右下角找到Design Compiler,单击 在弹出的菜单中选择Navigator,呵呵,使用吧
2023-07-14 21:34:181

导航仪 英文怎么说

导航仪avigraphnavigating instrumentnavigator这三个都行.
2023-07-14 21:34:283

javascript中的navigator.appname为何显示我的浏览器是Netscape?实际我装的是IE11

这个 navigator.appName 虽然是一个 只读字符串,但是 各个浏览器对他的处理都不一样了,向 opera用户就可以自定义 这个字符串.在最新版本的 IE 中,IE浏览器也会 伪装成其他 浏览器 来证明他自己的兼容性.
2023-07-14 21:34:361

window.navigator.geolocation 用户拒绝怎么办

这个是没办法的,如果用户拒绝的话下次就不会弹出了,这是没办法的事,因为用户有权拒绝,是没有什么办法的。基本上,使用谷歌地图时,直到用户点击允许或拒绝(将触发错误回调)才会加载成功回调。navigator.geolocation对象是获取位置信息的,geolocation对象包含一系列相关位置操作方法。由于涉及到隐私以及安全方面的考虑,在使用geolocation进行定位的时候,浏览器会询问用户是否允许共享位置信息;当用户进行“允许”或“不允许”操作之后,一般浏览器都会对当前站点缓存这个操作方式,这个的有效时间我也不太清楚!下次进入改站点时,将不会再弹出。用户拒绝之后无法获取位置,可以通过IP定位的方式进行定位,前提你得有一个相应的服务支持。
2023-07-14 21:34:441

Altium designer 怎么退出navigator,如图

可以直接关掉navigator窗口吧,或者点击左下角projects切换
2023-07-14 21:34:512

小程序navigator无法实现跳转点击没有反应

我用你的这段代码跑是正常跳转的(就用官方的示例代码,加了你的代码)。确认一下页面url地址是否正确,或者写个按钮加上点击事件,使用页面跳转API(网页链接)。
2023-07-14 21:35:061

anaconda navigator是干什么的

图形界面anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。 因为包含了大量的科学包,Anaconda 的下载文件比较大,如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和 Python)。
2023-07-14 21:35:152

如何卸载navigator 的navigationbar

1)Windows系统:单击开始——控制面板——单击程序和功能——想卸载哪个软件的话就单击哪个软件——直接卸载——下一步——等待卸载——完成,然后在看看是否卸载完成了。2)如果还是卸载不掉的话,那推荐你用卸载能力很强的腾讯电脑管家,管家管理页——软件管理——卸载——选择软件确认卸载就可以了,如果有顽固项残留项管家会提醒你进行清理。
2023-07-14 21:35:341

HTC G10 储存卡送的里面有一个navigator文件夹,占了1.5G,请问这个能删除么

navigator文件夹里面装的的导航软件,如果不需要gps导航功能的话可以删除
2023-07-14 21:35:482

提迈克Drive Navigator专用软件?

您好,你的问题,我之前好像也遇到过,以下是我原来的解决思路和方法,希望能帮助到你,若有错误,还望见谅!展开全部一、内容概述美国Varel国际公司成立于1947年,是世界上最大的独立供应商,全球钻头市场上的第5大公司,现拥有资本16亿美元,向石油、天然气、采矿和工业市场提供全套的牙轮钻头和固定刀具钻头。该公司技术研发一直走在世界前列,近年来更是开发出众多适用于特殊钻井环境的专用钻头。Varel国际公司应用其先进的钻头设计软件为导向钻井系统设计配套钻头,该种钻头在钻进的可控性和定向性方面取得了良好的效果。Varel国际公司在设计钻头的过程中主要应用了3个软件:(1)GeoScience测井数据分析软件一种室内鉴定岩性和测试岩石强度的应用软件,可以进行钻前和钻后的测井数据分析。(2)SPOT钻井软件一种虚拟的钻井模拟器,可以检验不同的切削结构设计和切削齿的布局是否合适。(3)CFD计算流体力学软件一种优化钻头流体特性的应用软件,可以确定最佳的喷嘴排列方向,从而优化钻头的水力特性,使设计出的钻头获得最佳效率。Varel国际公司推出的Navigator系列钻头(图1)是专门设计用于钻定向井的钻头产品,且可根据用户需要为特定用途设计专门的定向轮廓。该公司设计定向钻井用PDC钻头的理念,钻头是影响定向钻井成功与否的最重要因素,且每只钻头的设计都要与配套使用的旋转导向系统(RSS)、井的定向目标以及所钻地层相匹配。一只钻头钻至井眼目标的能力取决于其可导向性以及定向行为。图1 Navigator系列钻头Varel国际公司的工程师在设计钻头时会充分考虑配套使用的RSS的类型以及每种类型的功能和钻井特征,在设计过程中应用GeoScience、SPOT和CFD等工具。GeoScience是该公司的机械岩石性质模型,来自GeoScience的信息被输入到SPOT中。SPOT是一种能够对钻头动力学进行精密建模的设计软件,通过在实验室和现场进行单齿试验和全尺寸钻头试验得出,SPOT可为不同的钻井用途进行切削结构优化。CFD(计算流体力学)软件可验证钻头的喷嘴定向位置是否合理,从而保证钻头喷嘴结构和井底清洗效果的最优化。非常感谢您的耐心观看,如有帮助请采纳,祝生活愉快!谢谢!
2023-07-14 21:35:571

如何修改游览器的navigator.platform属性

platform 属性是一个只读的字符串,声明了运行浏览器的操作系统和(或)硬件平台。
2023-07-14 21:36:073

photoshop怎么设置navigator(导航器)能使缩略图是原图的100%大小

你好!导航下面有个滑动条,滑动条前边有个小白框,小白框里边是显示的大小,可以手动输入希望对你有所帮助,望采纳。
2023-07-14 21:36:263

c#后台怎么获取navigator.useragent

让浏览器的 ajax 发过来,然后你在后台的 request 的 headers 里面可以找到 useragent
2023-07-14 21:36:331

navigator.getmedia方法是不是一执行就打开了摄像头

调用摄像头$scope.photoErr = false;$scope.photoBtnDiable = true;var mediaStream = null,track = null;navigator.getMedia = (navigator.getUserMedia ||navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||navigator.msGetUserMedia);if (navigator.getMedia) {navigator.getMedia({video: true},// successCallbackfunction (stream) {var s = window.URL.createObjectURL(stream);var video = document.getElementById("video");video.src = window.URL.createObjectURL(stream);mediaStream = stream;track = stream.getTracks()[0];$scope.photoBtnDiable = false; $scope.$apply();},// errorCallbackfunction (err) {$scope.errorPhoto();console.log("The following error occured:" + err);});} else {$scope.errorPhoto();}
2023-07-14 21:36:411

火狐浏览器 不识别navigator.systemLanguage为什么呢?

  您好!很高兴为您答疑!  您可以使用navigator.language来获取客户端语言设置。  您可以在火狐社区了解更多内容。希望我的回答对您有所帮助,如有疑问,欢迎继续在本平台咨询。
2023-07-14 21:36:512

NAVIGATOR是什么车

领航员(Navigator)
2023-07-14 21:37:112

lincoln是什么车牌子navigator多少钱

lincoln是林肯牌子的汽车,navigator两款车型112点8万与122点8万。lincoln汽车是福特旗下的高端豪华品牌,创立于1917年,创始人为亨利利兰,亨利利兰同时也是凯迪拉克的创始人,1922年被福特公司收购,领航员Navigator是福特汽车公司生产的一款豪华的全尺寸SUV,创立了豪华运动型多功能汽车的新理念。领航员采用5点4升3气门新型发动机,最大输出功率达224千瓦,拥有127L油箱,全时四驱,领航员改进后的外观与内部设计在继承林肯轿车经典传统的同时,又结合了现代的表面处理与白色发光二极管技术。navigator的内容该车配备了一系列的豪华设施,如可加电热与制冷式前排座椅,电动展开式外脚踏板,电动折叠式第三排座椅,以及电动后举升门等,提高了驾乘的舒适性和便利性,改进后的外观与内部设计在继承林肯轿车经典传统的同时,又结合了现代的表面处理与白色发光二极管技术。领航员可选装经THX认证的Soundmark音响系统,该系统配备了DVD导航系统,提供语音激活,触摸屏系统界面和内嵌式6碟CD播放器等功能,领航员目前在美国密歇根州的Wayne工厂进行生产,福特汽车公司将于近期向中国大陆进口整车领航员,并从即日起开始由福特23家指定经销商进行预售。
2023-07-14 21:37:371

navigatorseries翻译?

navigator指的是(船只、飞机等的)领航员;(尤指旧时的)航海探险家,航海者;(飞机的)导航仪。series系列navigatorseries可翻译为领航者系列
2023-07-14 21:37:511

如何修改游览器的navigator.platform属性

我来放正解:Object.defineProperty(this , "navigator" , {value: { platform: "" }});
2023-07-14 21:38:002

商务领航Navigator2-1的初始密码是多少?

1,如果是cisco的设备,用户名和密码都是admin。2,如果是h3c的设备用户名是useradmin,密码是admin!搜索@#$%^
2023-07-14 21:38:083

如何修改游览器的navigator.platform属性

右击ie浏览器,选择属性,然后点击安全或打开浏览器—选择“工具”—Internet选项—点击安全。然后选择自定义级别,就会看到有关级别设置
2023-07-14 21:38:171

navigator.getusermedia 支持哪些浏览器

uc浏览器啊
2023-07-14 21:38:274

你好,我有一个领航者Navigator1-1的路由器,我想把他设置成无线中继怎么

路由器设置如下:1、将网线—路由器—电脑之间的线路连接好,启动电脑和路由器设备;2、启动设备后,打开浏览器,在地址栏中输入192.168.1.1进入无线路由器设置界面。(如进不了请翻看路由器底部铭牌或者是路由器使用说明书,不同型号路由器设置的默认都不一样。)3、设置界面出现一个登录路由器的帐号及密码,输入默认帐号和密码admin,也可以参考说明书;4、登录成功之后选择设置向导的界面,默认情况下会自动弹出;5、选择设置向导之后会弹出一个窗口说明,通过向导可以设置路由器的基本参数,直接点击下一步即可;6、根据设置向导一步一步设置,选择上网方式,通常ADSL用户则选择第一项PPPoE,如果用的是其他的网络服务商则根据实际情况选择下面两项,如果不知道该怎么选择的话,直接选择第一项自动选择即可,方便新手操作,选完点击下一步;7、输入从网络服务商申请到的账号和密码,输入完成后直接下一步;8、设置wifi密码,尽量字母数字组合比较复杂一点不容易被蹭网。9、输入正确后会提示是否重启路由器,选择是确认重启路由器,重新启动路由器后即可正常上网。
2023-07-14 21:38:341

chorm浏览器无法使用 navigator.geolocation.getCurrentPosition

和你一样的问题 ,如何解决?
2023-07-14 21:38:422

Anaconda-navigator 闪一下就退出是什么原因

删除你个人目录下的 .continuum 文件夹就行了(这是一个隐藏的文件夹,空的)step1. 打开终端step2. 输入 sudo rm -rf .continuumstep3. 输入电脑的密码完成上述步骤后,就能启动了
2023-07-14 21:39:081

如何修改游览器的navigator.platform属性

右击ie浏览器,选择属性,然后点击安全或打开浏览器—选择“工具”—Internet选项—点击安全。然后选择自定义级别,就会看到有关级别设置
2023-07-14 21:39:461

windows下anaconda navigator怎么新建python工程

方法/步骤下载安装Anaconda,建议安装32位版本。进入环境管理界面,启动的时候可能会比较慢。点击左下角的create按钮创建新的python环境等待新环境下载部署完成点击绿色小箭头进入控制台在控制台就可以对这个环境安装需要的模块和包,同时支持pip和conda命令要想从控制台启动这个环境,也只需要选择绿色小箭头对应菜单即可这个python环境的路径在这里:先设置显示隐藏文件夹,然后再去下面U0001f447路径
2023-07-14 21:39:551

三、Uni-app + vue3 页面如何跳转及传参?

Vue 项目往往需要使用 vue-router 插件,刚开始入门 Uni-app + Vue3 项目的同学,会不会想着路由使用 vue-router V4 版本不就可以了吗? 不怕大家笑话,我就是这样想的,毕竟我是第一次使用 Uni-app ,由于孕期记性贼差,所以我决定写成笔记,加深记忆。 uni-app 页面路由为框架统一管理的,我们需要在 page.json 文件里配置每个页面路由以及页面样式,有些类似小程序中的 app.json 文件,所以 uni-app 的路由用法和写法与 vue-router 不同。 项目初始化完成,对应的 page.json 文件为: uni-app 通过 pages 节点配置应用都有哪些页面,接收一个数组,每个元素都是一个对象,属性有: uni-app 页面路由跳转有两种方式:使用 navigator 组件跳转、调用API 跳转。 1、navigator组件跳转 类似于 a 标签,但是只能跳转到本地页面,目标页面必须在 page.json 中注册。 navigator 属性有: open-type 有效值 2、uni-app API 跳转 使用 API 页面跳转方式有: 框架以栈的形式管理当前所有页面, 当发生路由切换的时候,页面栈的表现如下: 方式1:onLoad 接收 方式2:setup语法糖接收 onLoad 函数是监听页面加载,接收的参数是页面传递的数据,是一个 object 类型。 看到这,相信很快就能上手 uni-app + vue3 项目路由喽,也可以参考官网教程:https://uniapp.dcloud.io/tutorial/page.html#%E8%B7%AF%E7%94%B1
2023-07-14 21:41:131

什么是sql navigator

是一款Oracle 数据库开发的第三方工具类似的有 pl/sql developertoadnavicatDbVisualizerAquaDataStudio等等
2023-07-14 21:41:211

sql Navigator 中有没有办法定义变量?

se masterdeclare @SEL_TYPE char(2)declare @SEL_CUNT numeric(10)set @SEL_TYPE = "U"/*user table*/set @SEL_CUNT = 10/*返回系统中用户表的数目*/select @SEL_CUNT = COUNT(*)from sysobjectswhere type = @SEL_TYPEselect @SEL_CUNT as "User table ""s count"如果要返回系统表的数目,可以用 set @SEL_TYPE = "S"可能这个例子并不能说明使用变量的好处,我只是想说明使用方法。当一组(几个甚至几十个)SQL语句都使用某个变量时,就能体会到他的好处了。
2023-07-14 21:41:281

如何解决Sql Navigator乱码

解决办法:开始->运行,输入regedit打开注册表找到HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOME0/NLS_LANG 修改NLS_LANG的值为SIMPLIFIED CHINESE_CHINA.ZHS16GBKufeff中文:SIMPLIFIED CHINESE_CHINA.ZHS16GBK英文:AMERICAN_AMERICA.WE8ISO8859P1
2023-07-14 21:41:351

怎么打开eclipse的导航窗口呢?

window--show view 输入outline
2023-07-14 21:41:434

下面这 var agent = navigator.userAgent.toLowerCase(); 是什么意思?

固定格式,返回由客户机发送服务器的 user-agent (可理解为浏览器名)头部的小写值(字符串是给机器看的变成小写方便系统存储和对比);navigator应为自定义的变量,里面应该存储了所有浏览器信息。
2023-07-14 21:41:551

var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; 这句话什么意思啊

var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; navigator.appVersion //获取浏览器版本navigator.appVersion.indexOf("MSIE") //indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符串,则返回 -1。 后面的 ? true : false 意思就是如果前面的条件为真,也就是说找了MSIE的字符串,那就说明浏览器是MSIE的, 那么结果就是为true , 否则就是为false下面是简单例子:5 > 4 ? true : false结果就是为true 因为5确实是大于4的, 也就是说条件成立,最终的结果就是 问号后面的值, 如果条件为假那么结果就是 冒号后面的.
2023-07-14 21:42:231

“anaconda navigator”是什么意思?

图形界面anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。 因为包含了大量的科学包,Anaconda 的下载文件比较大,如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和 Python)。
2023-07-14 21:42:321

微信小程序——列表导航吸顶效果

众多类似商城项目中,都会有列表分类标签随着界面滚动吸顶的效果 APP中实现相关功能很容易,h5也可以动态操作DOM来设置 微信小程序没有DOM,该怎么实现呢? 其实这个场景还是比较简单的,正常情况下导航标签是在列表中间的,滑到顶部时吸顶,再拉下来时又回到原来的位置 根据场景,有两个参考思路: 1、顶部定位一个常在的同样的导航标签,通过页面的 scrollOffset 来控制显隐即可 2、通过动态添加 fixed 样式,来动态改变标签在页面中的位置 ps:不过第二种思路会有一个缺陷就是切换位置时页面会因为少了一部分而上移,所以还是需要补白,所以还是用第一种思路 我这里是用了自定义导航栏的,所以实现上会有所不同,如果是用系统导航栏可以稍微调整一下,因为偏移量会有所区别 CSS部分 JS部分 其中 CacheUtil.naviStatuHeight 这个是我应用启动时获取的导航+状态栏高度,X和其他机型还是有所区别,如果是系统导航栏的话这些相关逻辑都可以省略 这里为什么用navigator而不用view呢? 因为navigator是原生组件,可以在最上层,因为有可能列表内容有原生组件的话滑动就会有问题,所以navigator在不设置url的情况下和view的效果差不多,故采用navigator cover-view:bug: 自定义组件嵌套 cover-view 时,自定义组件的 slot 及其父节点暂不支持通过 wx:if 控制显隐,否则会导致 cover-view 不显示,而且使用的版本限制也很多,所以就不考虑
2023-07-14 21:42:451

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