当前位置:首页 » 安卓系统 » android回退栈

android回退栈

发布时间: 2022-12-23 08:56:09

A. Android activity中加载了webview,页面跳转后总是要点击两次手机的返回按钮才能回到上一页

WebViewClient中的shouldOverrideUrlLoading方法如下重写:

java">@Override
(WebViewview,Stringurl)
{
view.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
view.loadUrl(url);
returnsuper.shouldOverrideUrlLoading(view,url);
}

onKeyDown如下重写:

@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent)
{
if(keyCode==KeyEvent.KEYCODE_BACK){
if(webView.canGoBack()){
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webView.goBack();
returntrue;
}else{
finish();
returntrue;
}
}
returnfalse;
}

B. android 怎么通知回退栈中的fragment刷新

到的问题:
通过FragmentTransaction的replace方法会导致,每次都会重新调用fragment的onCreateView()方法,浪费时间。

解决方法:
通过FragmentTransaction的hide和show方法来实现fragment的显示和隐藏,这样就不会重复调用onCreateView函数了。

FragmentTransactioin 可以用来添加,删除fragment,也可以控制fragment的显示和隐藏。

这是如果调用addToBackStack(null),此时的状态就会被保存在回退栈,按返回键的时候就会显示出栈顶的

getSupportFragmentManager().popBackStack() 这个方法可以让栈顶的fragment出栈。

只有在程序运行时被动态添加的fragment才会被添加到后退栈。
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, newFragment,"testa")
.addToBackStack(null)
.commit();

程序跑起来之后,通过这个方法后退栈数才会加一,如果在代码中一口气添加多个,再运行程序,getSupportFragmentManager().getBackStackEntryCount()得到的后退栈数值为零。

C. Android基础之Activity 运行模式与回退栈

LaunchMode 定义的是activity实例与task之间的关系,可以通过下面的两种方式来定义:

在Activity A中启动B,可以利用Activity B在清单中的launchmode定义,也可以在A中调用startActivity()的时候通过intent的flag传入,当两种方式都有定义,intent的flag参数会覆盖掉B原有的定义。

利用Activity 元素的launchMode属性
launchMode属性指定Activity如何被运行到一个task中。launchMode的值有四种:

默认, 每次启动Activity系统都会产生一个新的实例,并且把intent发送给新产生的实例,这个Activity可以被实例化多次,每个实例可以属于不同的task,每个task也可以保有多个此Activity的实例。

如果当前task 的回退栈栈顶已经存在一个此Activity的实例,系统通过调用这个实例的onNewIntent()方法把intent发送给这个Activity实例,而不是创建一个新的此Activity的实例。这个Activity也可以被实例化多次,每个实例可以属于不同的task,每个task可一个保有多个实例(仅限于此Activity已存在的实例不在栈顶)
注意:
应用场合如下:不想出现2个同样的activity在顶部。比如用户正在一个activity阅读信息,这时来了notification,用户点击后应该更新这些信息,而不是新建一个activity,这样在点击back时,就不会出现回到旧信息activity的情况了。这种情况正是下面这段英语提到的。
Note: When a new instance of an activity is created, the user can press the Back button to return to the previous activity. But when an existing instance of an activity handles a new intent, the user cannot press the Back button to return to the state of the activity before the new intent arrived in onNewIntent()
.
例如,当前回退栈中有A,B,C,D四个Activity,全部是Standard,在D中调用startActivity()去启动B,intent的flag设置成FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK,系统发现栈中有B,会先销毁这个B,再原位置重建B,清空CD,而不是把这个新建的B的实例压入栈顶,这里之所以会销毁B再新建B,因为B的launchmode是Standard,无论什么情况下启动,都需要new一个B的实例,但如果此时B是SingleTop的,系统会把这个intent通过onNewIntent传给已经在栈中的B的实例,不需要销毁再创建,仍需要清空CD。

系统会创建一个新的task并且把这个实例放在栈底( 此处有疑问,测试发现并不一定是栈底 ),但是,如果在一个单独的task中已经存在一个此Activity的实例,系统会把intent通过onNewIntent()发送给这个实例( 测试发现如果在回退栈中,该Activity的上面还有其他Activity,启动此Activity会清空栈中此Activity上面的其他Activity ),而不是创建一个新的实例。同一时间在只有一个此Activity的实例存在于系统中。

与SingleTask一样,不同的是SingleTask的Activity所在的task中可以有其他的Activity,而SingleInstance的Activity独占一个task,并且在整个系统中只有唯一的一个实例。由这个Activity启动的其他Activity都会在新的task中打开。

另一个例子,系统自带浏览器APP把浏览器Activity声明为SingleTask,通过在Activity标签里的launchMode进行指定,这意味着如果你发送一个intent启动浏览器,不管是为浏览器新开启一个task还是从浏览器已经在后台保有的task中启动浏览器,浏览器Activity与你的APP不在同一个task。

不管一个Activity是不是在一个新的task中启动,点击返回都会返回前一个Activity。不过,如果启动一个LaunchMode为singleTask的Activity,如果该Activity此时在一个处于后台的task中,整个task会变成前台task,此时,回退栈会包含由这个后台task携带过来所有Activity,放在回退栈的栈顶,下图说明这种情况。

在一个新的task里启动Activity. 如果已经有Activity实例运行在某一task中,启动这个Activity会把该实例所在的task带到前台,由该实例的onNewIntent()来接收新的intent。

如果被启动的Activity就是当前的Activity,这个已经存在的实例通过onNewIntent()接收intent,不会产生新的实例。

被启动的Activity如果已经存运行于当前task,回退栈中所有在此Activity上面的Activity都将被销毁,此Activity通过onNewIntent()接收新的intent。
例如,一个task中有A,B,C,D,四个Activity,如果D 调用startActivtiy()启动Activity B,C和D会被销毁,B接收这个intent,回退栈中有A,B。
上例中的Activity B的实例,或者通过onNewIntent()接收新的intent,或者销毁新建来处理新的intent。如果B的launchmode是standard,并且没有设置FLAG_ACTIVITY_SINGLE_TOP,那么B会被销毁重启,如果是其他launchmode或者设置了FLAG_ACTIVITY_SINGLE_TOP,则会通过onNewIntent()接收。
FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK结合使用会有个不错的效果。
如果启动的Activity位于task的底部,它会把所在task带到前台,并且清理状态至root状态,当从通知栏里打开一个Activity的会非常有用。

Affinity指的是一个Activity偏向于从属于哪个task,默认情况下,一个APP内的所有Activity互相之间共享一个affinity的值,所以,所有同一APP下的所有Activity都偏向于从属于同一个task。但是,这个值是可以更改的,不同APP内的Activity可以共享一个affinity,同一个APP内的Activity也可以被分配不同的affinity的值。
affinity的值可以通过修改Activity标签的taskAffinity属性来修改。
这个属性接收一个String的值,必须在manifest标签范围内是唯一的值,因为系统是通过名称来标识APP的affinity的值的。
Affinity作用于以下两种情况:

通过startActivity()启动一个新的Activity时,默认情况下,新的Activity会被压入与启动者相同的回退栈中。但是,如果在启动Activity的时候,使用了FLAG_ACTIVITY_NEW_TASK 这个标志,系统会为新的Activity寻找一个新的task。通常情况下,是一个新的task。但是也并不是必须的。如果系统中有一个task的affinity值与新的Activity的值相同,新的Activity会被分配到这个task中。如果没有这样的task,就启动一个新的task。如果这个标志产生了一个新的task,当用户点击home键离开的时候,必须要有某种方式能够使用户返回到这个task来。有些实体(例如通知管理器)总是从一个外部task中启动Activity,所以在通过startActivity()启动新的Activity时总是需要传递FLAG_ACTIVITY_NEW_TASK 这个标志。如果你有一个Activity可以被外部实体可能这个标志启动,注意用户可以有一种独立的方式回到启动它的task,例如点击启动图标。

这种情况下,一个Activity可以动启动它的那个task移动到它的affinity值对应的task中,当那个task回到前台。例如,假设,一个报告指定城市天气情况的Activity作为一个旅行APP的一部分,它跟其他处在同一APP的Activity一样有一个相同的affinity值,并且允许通过这个属性来调整目标task。当你的一个Activity启动了这个天气预报Activity,它默认跟你的Activity在一个task里,但是,当旅行APP进入到前台,这个天气预报Activity又会被重新分配给旅行APP并且在旅行APP内展示。
提示:
如果一个APK文件从用户的角度看是多款APP,可能需要这个属性来设置不同的affinity来关联不同的APP。

如果用户离开一个task太长时间,系统会清除task中的所有Activity仅仅保留这下根Activity。当用户返回到这个task的时候,只有这个根Activity会被恢复。系统通过这种方式来处理,是因为经过相当长的一段时间之后,用户已经抛弃他们曾经正在做的事情,计划再回来的时候做点新的事情。

你可以通过如下属性来更改这种行为:

参考文献:
Tasks and Back Stack
<activity>
Android 阅读Tasks and Back Stack文章后的重点摘抄

热点内容
编程linux系统 发布:2025-04-05 06:04:14 浏览:249
表格如何增减密码 发布:2025-04-05 06:00:33 浏览:191
存储卡sandisk 发布:2025-04-05 06:00:26 浏览:38
dll编译出错求助 发布:2025-04-05 05:59:44 浏览:709
模拟人生java 发布:2025-04-05 05:53:58 浏览:553
日本免费云服务器色 发布:2025-04-05 04:58:52 浏览:865
linuxcpp 发布:2025-04-05 04:53:38 浏览:748
安卓字体哪个最好 发布:2025-04-05 04:46:37 浏览:650
什么是hdb3码编译码 发布:2025-04-05 04:40:20 浏览:504
编译原理运算符 发布:2025-04-05 04:37:50 浏览:521