我想保存我的应用程序的状态,以便在从关闭状态重新打开时,最后一个片段是可见的并且后备堆栈被保留.我希望每次关闭应用程序时都保留此状态,而不仅仅是方向更改或系统杀死应用程序以释放资源(就像使用onSaveInstanceState()/ 时的情况一样)onRestoreInstanceState().
到目前为止,我已经能够通过将状态保存到SharedPreferences并在以后恢复它来按计划恢复上一个片段及其状态.但是,这不会保留片段后备栈,因此当用户加载应用程序并按下后退按钮以在应用程序流中"向上"移动时,应用程序退出而不是上升.
此时我需要的是能够访问应用程序后台堆栈并在必要时将其保存到捆绑包中,就像系统所做的那样onSaveInstanceState().我已经阅读了文档,FragmentManager.saveFragmentInstanceState()但我不知道如何使用它来实现我的目标.任何人都能指出我正确的方向吗?
我正在使用Android兼容性库中的片段实现.
我的应用程序中有各种活动,流程非常复杂.我想要做的是,只要连接usb设备,我想清除并完成后台堆栈活动,然后完成当前活动和System.exit(0)以关闭应用程序.
我已经实现了usb设备监听器.我想知道如何清除和完成堆栈活动(如果有的话,它不会每次都有任何后端堆栈活动)然后完成当前的活动.
此外,如果我的活动A在顶部,并且它在后堆栈中有2个活动(B,C).现在,如果活动A在后台运行并且USB连接,那么只有活动A会听到它吗?(我在每个活动中都实现了usb接收器.)
如果没有我的应用程序崩溃,我该如何实现
谢谢
我有一个应用程序,以一个开头SplashScreenActivity.然后,显示a LoginActivity,或者如果用户已经登录,MainActivity则显示a.如果应用程序已在运行,SplashScreenActivity则会被解除以下内容
//SplashScreenActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Adding this check for following cases
if (!isTaskRoot())
{
String intentAction = getIntent().getAction();
if (getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) && intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
finish();
return;
}
if(getIntent().getCategories().contains(GCMIntentService.INTENT_CATEGORY_GH_NOTIFICATION)){
finish();
return;
}
}
Run Code Online (Sandbox Code Playgroud)
出现问题
如果我从PlayStore等其他活动启动应用程序,它会在正确的活动中恢复,如果已经运行的话.这是Intent我用来在第二个应用程序中重现
//AnotherApplication.apk
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("my.package.name");
startActivity(launchIntent);
Run Code Online (Sandbox Code Playgroud)
但是,这个动作在某种程度上打破了Backstack.它不是在后台关闭应用程序MainActivity,而是重新启动应用程序.
//MainActivity.class
@Override
public void onBackPressed() {
if (getNavDrawerMain().isDrawerOpen()) {
getNavDrawerMain().closeDrawer();
} else {
closeApp();
}
}
protected void closeApp() { …Run Code Online (Sandbox Code Playgroud) 我在我的一个片段中使用TabLayout,并使用viewPager在标签下方的两个片段之间切换.
当我单击其中一个较低片段中的FAB时,我加载一个新片段(用于输入).
但是 - 当我按下BACK按钮时,TabLayout会显示但没有任何一个较低的片段(由页面表示).
那么我做错了什么?

使用TabLayout的片段:CustomTemplatesFragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_custom_templates, container, false);
final TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText(R.string.macro_tab));
tabLayout.addTab(tabLayout.newTab().setText(R.string.lifestyle_tab));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
final CustomTemplatesPagerAdapter adapter = new CustomTemplatesPagerAdapter
(getFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void …Run Code Online (Sandbox Code Playgroud) android android-fragments back-stack fragment-backstack android-tablayout
我创建了一个 android 应用程序(示例 APK和Github Repo),我在其中实现了一个BottomNavigationBarwith ViewPager. 导航没问题,但我不知道如何在像 Instagram 这样的 viewpager 中处理返回堆栈。
我尝试了下面的代码,但这样我必须创建一个我从不导航的不必要的片段。
view_pager_main_activity?.currentItem = view_pager_main_activity.currentItem - 1
Run Code Online (Sandbox Code Playgroud)
假设我只是将应用程序启动到第一页,然后通过 BottomNavBar 导航到第三页,但是现在如果我单击后退按钮,我会通过第二页返回到第一页。所以这样我创建了不需要的第二页。
这是 onBackPressed() 的整个回栈过程
override fun onBackPressed() {
if (view_pager_main_activity?.currentItem == 0) {
if (view_pager_main_fragment?.currentItem == 0) {
val recyclerView = findViewById<RecyclerView>(R.id.listRecyclerView)
val appbarHome = findViewById<AppBarLayout>(R.id.appbar_home)
val layoutManager = recyclerView?.layoutManager as LinearLayoutManager
when {
layoutManager.findFirstCompletelyVisibleItemPosition() == 0 -> {
super.onBackPressed()
}
supportFragmentManager.backStackEntryCount != 0 -> {
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}
else -> {
layoutManager.scrollToPositionWithOffset(0, 0) …Run Code Online (Sandbox Code Playgroud) android instagram back-stack bottomnavigationview android-viewpager2
是否有可能从代码中获取当前的Activity堆栈?
这是我的用例:
A - > B - > c - > D - > ......
一些活动将在将用户发送到新屏幕后完成,其他一些则不会
我需要检查是否按下BACK按钮会将用户带到活动A或任何其他按钮,因为在当前显示的活动中我有一个完成活动的按钮,按钮的图标是不同的天气你将被带到tha活动A或其他活动.
提前致谢,
再见,毛里齐奥
我有一个带有操作栏和动作栏标签的活动.当我从选项卡的内容中选择一个项目时,我正在尝试用新的替换当前片段,将事务添加到后台堆栈,并隐藏选项卡.
我通过将操作栏导航模式更改为标准来隐藏选项卡.
问题是,当我按下后退按钮时,我只是使用操作栏获得一个空白视图(在标准模式下)..片段事务似乎没有被反转.
如果我不通过将导航模式更改为标准来隐藏选项卡,则事务反转工作正常.
我已经尝试覆盖背面按下以将导航模式更改回选项卡,但它不起作用.
有人能告诉我他们将如何实现这一目标吗?
以下是隐藏选项卡并执行片段事务的代码:
ActionBar actionBar = getActivity().getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
Fragment albumListFragment = new AlbumListFragment();
albumListFragment.setArguments(bundle);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, albumListFragment);
ft.addToBackStack(null);
// Commit the transaction
ft.commit();
Run Code Online (Sandbox Code Playgroud)
为清楚起见:我希望在提交此事务后回退,标签将返回到前一个片段的视图.在按下后,它没有显示标签或片段.
我的Android平板电脑应用的布局包括项目列表和详细信息视图.选择列表项时,关联的内容将显示在详细信息视图中.
+--------+-------------+
| Item 1 | |
+--------+ Item |
| Item 2 | details |
+--------+ |
| Item 3 | |
+--------+-------------+
Run Code Online (Sandbox Code Playgroud)
详细信息视图是以Fragment编程方式膨胀到FrameLayout占位符中的:
<FrameLayout
android:id="@+id/detail_fragment_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent">
Run Code Online (Sandbox Code Playgroud)
这是Fragment操作:
getSupportFragmentManager()
.beginTransaction()
.replace(containerViewId, fragment, fragmentTag)
.addToBackStack(backStackStateName)
.commit();
Run Code Online (Sandbox Code Playgroud)
多个实例[Dx]的DetailsFragment,当用户相继选择一个项目被添加到堆栈中.
[D3]
[D2] [D2]
[D1] -> [D1] -> [D1]
Run Code Online (Sandbox Code Playgroud)
因此,用户需要多次按BACK按钮从后台弹出实例以清空详细信息视图.
我怎么能取代现有的实例[Dx]中DetailsFragment对返回堆栈时,fragmentTag现有的fragment相匹配的fragmentTag新的fragment?
[D1] -> [D2] -> [D3]
Run Code Online (Sandbox Code Playgroud) 简单的问题,但似乎无法回答...如何清除fragmentManager后栈而不弹出片段?
我这样理解:
后栈条目=使用addToBackStack命令预先保存的事务列表.例如:"将片段1替换为片段2".
popBackStack =最后保存的transatcion反向.例如:"将片段2替换为片段1".
假设我做了第一笔交易:F1-> F2并将此交易添加到后台.当我按下后退按钮时,F2-> F1将会发生.
好的但是..
我改变了主意,想要清理后面的堆栈.我希望用户使用F2片段但是当他/她按下后退按钮时,Activity应该关闭,就像后面的堆栈是空的一样.
我需要这样的东西:
for(int i=0;i<getFragmentManager().getBackStackEntryCount();i++){
getFragmentManager().getBackStackEntryAt(i).remove();
}
Run Code Online (Sandbox Code Playgroud)
编辑 我试图向复杂的情况提出简单的问题,我得到简单的答案;)Abhishek Patel的答案非常好,但它不是我想要的.仍然是一个很好的答案.
只是为了澄清: android中的后台堆栈不是完全可编辑的列表,如:
我们不能做"删除交易3"来做:
我们无法清除所有后端堆栈并保持最后一个可见的碎片活着.
我们可以将backstacks记录删除到某个位置,例如:"删除所有事务到事务2"以获得:
在屏幕上,您将看到交易2的效果.
为什么我需要这个?
我认为我可以创建一个片段,它将是"主要片段".这个主要片段将使用一个接口来告诉它现在显示的任何活动,现在显示这个boss片段,以及之前发生的任何事情 - 不再重要了.
(F) - 片段,(A) - 活动
(F) - 嘿老兄.我是老板,我可见并且依附于你.请为我清理你的背包,但保留我的交易,这让我来到这里.
(A) - 对不起男人......你应该在交易前告诉我清理我的背包,这样我就可以在新的背包上添加你的交易了.
我想知道现代Android开发世界中有关Back Stack管理的常见做法或模式,特别是处理应用程序被杀或崩溃的情况,以及系统尝试重新创建其活动,因为应用程序创建的任务仍然存在.
以下是在示例应用上演示上述行为的视频:https://www.dropbox.com/s/pkm88dvdpzsw9lm/IMG_2334-480.mov?dl = 0
这里是源代码 - 基本上只是一个使用Android Studio向导创建的简单应用程序:ssh://git@github.com:lukaszs-appdate/crashingtask.git
假设该应用程序在开始时显示登录活动.然后当用户登录时从服务器下载数据并允许用户操作数据,启动其他活动,操纵应用程序的状态等.重要的假设是当用户例如切换到不同的应用程序并返回到我们的应用程序时,他们看到最后一个活动,而不是回到登录.因此,我认为文档https://developer.android.com/guide/components/activities/tasks-and-back-stack.html中的标记组合不足以解决问题.
问题是,当:a)应用程序崩溃并重新启动,或b)使用Android中的任务切换按钮将应用程序移至后台,然后在Android Studio中手动终止并通过点击任务图标然后返回Android尝试从任务中重新创建活动.我想让它在这些事件的情况下从头开始启动应用程序并显示登录屏幕.
我看到的唯一解决方案是除了登录之外的所有活动的一些丑陋的父类,我们将检查是否设置了一些伪会话变量,如果不是,则假设应用程序已重新启动并替换整个任务堆栈登录活动,或者做一些finish()调用或其他类似臭的东西.
还有其他想法吗?当有问题的应用程序被杀死时,Android是否只能删除应用程序创建的任务?
一个干净的解决方案是使用某种会话管理,允许任何活动有效地恢复应用程序的业务状态,使用户能够从任何活动中正确地恢复应用程序,即使它已被杀死.但这是另一个讨论.