小编Gab*_*abi的帖子

Backstack管理:仅在所有者的初始化阶段才必须创建重启器

我在MainActivity中使用底部导航栏来处理一些片段。这是用于在它们之间切换的代码:

private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
    if (item.isChecked &&
        supportFragmentManager.findFragmentById(R.id.act_main_fragment_container) != null
    )
        return@OnNavigationItemSelectedListener false
    val fragment =
        when (item.itemId) {
            R.id.navigation_home      -> fragments[0]
            R.id.navigation_bookings  -> fragments[1]
            R.id.navigation_messages  -> fragments[2]
            R.id.navigation_dashboard -> fragments[3]
            R.id.navigation_profile   -> fragments[4]
            else                      -> fragments[0]
        }
    this replaceWithNoBackStack fragment
    return@OnNavigationItemSelectedListener true
}
Run Code Online (Sandbox Code Playgroud)

方法replaceWithNoBackstack只是此的简写:

supportFragmentManager
    ?.beginTransaction()
    ?.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
    ?.replace(containerId, fragment)
    ?.commit()
Run Code Online (Sandbox Code Playgroud)

问题是,当我在它们之间更快地切换时,我的应用程序崩溃,但出现以下异常:

java.lang.IllegalStateException:仅在所有者的初始化阶段,必须在androidx的androidx.fragment.app.Fragment.performCreate(Fragment.java:2580)的androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:59)上创建重新启动器。 androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1237)处于androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1302)处的fragment.app.FragmentManagerManager.mpl.moveToState(FragmentManagerImpl.java:837) androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2075)上的.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439),位于androidx.fragment.app.FragmentManagerImpl。在androidx.fragment.app上的executeOpsTogether(FragmentManagerImpl.java:1865)在androidx.fragment.app处的FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1820)在androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1726)在androidx.fragment。 $ 2.run(FragmentManagerImpl.java:150)在android.os.Handler.handleCallback(Handler.java:789)在android.os.Handler.dispatchMessage(Handler.java:98)在android.os.Looper.loop(Looper .java:164),位于android.app.ActivityThread.main(ActivityThread.java:6709),位于com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote)的java.lang.reflect.Method.invoke(本机方法) .java:240),位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769),我是我已经搜索了很多,却找不到答案。

如果我进行API调用,将应用程序置于后台,等待响应,并且在我返回到应用程序时,由于我试图立即显示对话框片段而导致应用程序崩溃,我也会遇到此错误(原因是我认为这是因为在显示对话框片段时,从后台返回时重新创建片段的事务仍在进行中。我通过设置对话框的500ms延迟来解决此问题,因为我找不到其他解决方案。

请询问您是否需要有关此的更多详细信息。先感谢您!

可能的温度解决方案

编辑 我通过将应用程序兼容性降低到了androidx.appcompat:appcompat:1.0.2这个级别来解决了这个问题,但这只是一个临时解决方案,因为我将来必须对其进行更新。我希望有人能解决。

编辑2 我通过从片段事务中删除setTransition()解决了该问题。至少我知道android应用总体上没有良好过渡的原因

编辑3 也许是避免此问题并让事情顺利进行的最佳解决方案,只是使用ViewPager处理底部栏导航

android android-fragments kotlin back-stack fragmentmanager

11
推荐指数
3
解决办法
2036
查看次数

在Android App中存储机密和凭据

我正在使用AWS Cognito,我需要在我的Android应用程序中的某处存储一些凭据和机密,以便稍后使用它们来登录/注册/注销用户.

一些消息来源建议将凭证存储在项目gradle.properties文件中.从那里,凭证将被检索为BuildConfig.FIELD_NAME.我可以100%确定在逆向工程时无法从apk中提取这些内容吗?

我想到的另一种方法是使用非对称加密算法(使用公钥 - 私钥)加密凭证,并在需要时在运行时解密它们,但同样,我需要在我的应用程序中的某个位置存储公钥以解密证书.这不再起作用,因为可以提取反编译apk的公钥.

我已经做了很多研究,但在这种情况下我找不到任何帮助.几乎每篇文章都指的是如何存储密码等凭证,但这不是相同的情况,因为我没有从服务器或运行时的任何地方检索我的秘密和凭据.进行API调用以获取凭据再次是一件坏事.

那么,我怎样才能尽可能安全地做到这一点?我在等你的解决方案!谢谢

编辑: 密钥库并没有真正起作用,因为在将它们添加到密钥库之前我必须从某处获取秘密

security encryption android credentials amazon-web-services

8
推荐指数
1
解决办法
175
查看次数

拖放 RecyclerView 的第一项会移动多个随机位置

目前,我有一个 RecyclerView 实现新的 ListAdapter,使用 SubmitList 来区分元素并继续自动更新 UI。

最近,我必须使用众所周知的 ItemTouchHelper 来实现对列表的拖放。这是我的实现,非常简单:

class DraggableItemTouchHelper(private val adapter: DestinationsAdapter) : ItemTouchHelper.Callback() {
private val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
private val swipeFlags = 0

override fun isLongPressDragEnabled() = false
override fun isItemViewSwipeEnabled() = false

override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
    return makeMovementFlags(dragFlags, swipeFlags)
}

override fun onMove(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    target: RecyclerView.ViewHolder
): Boolean {
    val oldPos = viewHolder.adapterPosition
    val newPos = target.adapterPosition

    adapter.swap(oldPos, newPos)
    return true
}

override fun onSwiped(viewHolder: …
Run Code Online (Sandbox Code Playgroud)

android scroll drag-and-drop android-recyclerview

6
推荐指数
1
解决办法
1595
查看次数