如何重新附加片段(片段未附加到活动 Kotlin)

Posted

技术标签:

【中文标题】如何重新附加片段(片段未附加到活动 Kotlin)【英文标题】:How to reattach Fragment (fragment Not not attached to an activity Kotlin) 【发布时间】:2021-09-02 07:40:17 【问题描述】:

我对这个错误感到沮丧片段未附加到活动,我有一个片段开始一个活动,活动开始另一个活动等等F -> A1 -> A2 -> A3,在我完成最后一个A3之后我打电话回去参加主办的活动

val intent = Intent(applicationContext, TabbarActivity::class.java)
        intent.putExtra("finish", "true")
        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
        startActivity(intent)
        finish()

但是当我设置Intent.FLAG_ACTIVITY_CLEAR_TASK 时,它会将我的片段从活动中分离出来,然后我收到此错误Fragment not attached to an activity,如果我重新运行我的应用程序,一切都会正常工作。

这里是宿主活动

private var bottomNavigation: BottomNavigationView? = null

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_tabbar)


        val finish = intent.getStringExtra("finish")

        bottomNavigation = findViewById(R.id.bottomNavigationView)
        val navigationController = findNavController(R.id.fragment)

        bottomNavigation?.setupWithNavController(navigationController)
        bottomNavigation?.itemIconTintList = null


        val firstFragment: Fragment = Fragment1()
        val secondFragment: Fragment = Fragment2()
        val thirdFragment: Fragment = Fragment3()
        val forthFragment: Fragment = Fragment4()
        var active = firstFragment


        supportFragmentManager.beginTransaction().add(R.id.containerb, forthFragment, "4").hide(forthFragment).commit()
        supportFragmentManager.beginTransaction().add(R.id.containerb, thirdFragment, "3").hide(thirdFragment).commit()
        supportFragmentManager.beginTransaction().add(R.id.containerb, secondFragment, "2").hide(secondFragment).commit()
        supportFragmentManager.beginTransaction().add(R.id.containerb, firstFragment, "1").commit()

        if (finish.equals("true"))

            bottomNavigation?.setSelectedItemId(R.id.ordersFragment);
            supportFragmentManager.beginTransaction().hide(active).show(thirdFragment).commit()
            active = thirdFragment
        


        bottomNavigation?.setOnNavigationItemReselectedListener 
            when (it.itemId) 
                R.id.Fragment1 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(firstFragment).commit()
                    active = firstFragment

                
                R.id.Fragment2 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(secondFragment).commit()
                    active = secondFragment

                
                R.id.Fragment3 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(thirdFragment).commit()
                    active = thirdFragment

                
                R.id.Fragment4 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(forthFragment).commit()
                    active = forthFragment

                
            
            true
        


        bottomNavigation?.setOnNavigationItemSelectedListener  item ->
            when (item.itemId) 
                R.id.Fragment1 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(firstFragment).commit()
                    active = firstFragment

                
                R.id.Fragment2 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(secondFragment).commit()
                    active = secondFragment
                
                R.id.Fragment3 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(thirdFragment).commit()
                    active = thirdFragment
                
                R.id.Fragment4 -> 
                    supportFragmentManager.beginTransaction().hide(active).show(forthFragment).commit()
                    active = forthFragment
                
            
            true
        

    

我什么时候收到这个错误?

在完成最后一个活动并且用户导航返回后,用户可以收到通知,当通知请求我尝试过的上下文requireContext(), this@..Activity, applicationContext, activity.context 时,错误从这个方法开始,以及获取上下文的所有可能性这里是 Fragment3

override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)

        createNotificationChannele()

private fun newOrderOffers() 
        val uid = FirebaseAuth.getInstance().uid ?: ""
        val firestore = FirebaseFirestore.getInstance()
        val fireRef = firestore.collection("inProcess").whereEqualTo("userUid", uid)
        fireRef.addSnapshotListener  value, error ->
            if (value != null) 
                value.documentChanges.forEach 
                    if (it.type == DocumentChange.Type.ADDED) 

                        SendNotificationWhenSelected()

                    
                
            
        

    

private fun createNotificationChannele()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            val channel = NotificationChannel(chanal_id, chanale_name,
                NotificationManager.IMPORTANCE_HIGH).apply 
                lightColor = Color.RED
                enableLights(true)
            
            val manager = this.context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(channel)
        

    
private fun SendNotificationWhenSelected()
        val notification =
            NotificationCompat.Builder(requireContext(), chanal_id) // the error in this line
                .setContentTitle("...")
                .setContentText("....")
                .setSmallIcon(R.drawable.....)
                .setPriority(Notification.PRIORITY_HIGH)
                .setAutoCancel(true)
                .build()

        val notificationManager = NotificationManagerCompat.from(requireView().context)
        notificationManager.notify(notification_id, notification)

logcat 错误

java.lang.IllegalStateException: Fragment Fragment33131d71 (ee9f090f-fa37-46a0-9fda-b7e9831db10d) not attached to an activity.
        at androidx.fragment.app.Fragment.requireActivity(Fragment.java:833)
        at com.qp.dele.fragment.Fragment3.SendNotificationWhenSelected(3Fragment.kt:295)
        at com.qp.dele.fragment.Fragment3.access$SendNotificationWhenSelected(Fragment3.kt:40)
        at com.qp.dele.fragment.Fragment3$newOrderOffers$1.onEvent(Fragment3.kt:272)
        at com.qp.dele.fragment.Fragment3$newOrderOffers$1.onEvent(Fragment3.kt:40)
        at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2(Query.java:1133)
        at com.google.firebase.firestore.Query$$Lambda$3.onEvent(Unknown Source:6)
        at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
        at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(Unknown Source:6)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

【问题讨论】:

请编辑您的问题并使用来自 logcat 的堆栈跟踪发布完整的错误消息。 编辑 @DavidWasser 先生 在您的第一次运行中,片段 3 是否会进入循环以发送通知? SendNotificationWhenSelected() 是在第一次运行时触发还是仅在您完成并返回到出现错误的开始时触发? newOrderOffers() 正在被调用并生成异常。这是从哪里调用的? 在fragment3 onCreatedView()方法中调用 【参考方案1】:

问题似乎在于旧的Fragment 仍然存在,并且在与旧的Activity 分离后仍会收到 Firebase 回调。当旧的 Fragment 分离/销毁时,您需要删除 Firebase 回调。

这就是为什么您在返回TabbarActivity 时会看到此问题,但在您第一次启动应用程序时却没有。

【讨论】:

这听起来与这个问题无关。您应该发布另一个包含此问题详细信息的问题 非常感谢,我刚刚删除了 detached/destroyed 的回调,现在工作正常,从昨晚开始我一直在互联网上搜索,我只是浪费了很多时间,知道问题是解决方案,再次感谢。

以上是关于如何重新附加片段(片段未附加到活动 Kotlin)的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.IllegalStateException:片段未附加到活动

OnDetach/onAttach 片段重新创建片段活动

片段未附加到上下文

何时片段不附加到活动而仅附加到上下文?

活动重新创建意图附加内容为空

Android在活动视图中附加片段获取片段已添加错误