How to reattach Fragment (fragment Not not attached to an activity Kotlin)

Viewed 269

I'm getting frustrated with this error Fragment not attached to an activity, I have a fragment that starts an activity and activity starts another activity so on and so forth F -> A1 -> A2 -> A3, after I finished with the last one A3 I call to go back to the hosted activity

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()

but when I set Intent.FLAG_ACTIVITY_CLEAR_TASK it disattached my fragment from the activity and then i get this error Fragment not attached to an activity, every thing will work fine if i rerun my app.

here is the host 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
        }

    }

when im getting this error?

after finish with the last activity and the user navigate back user can receive a notification the error starts with this method when the notification request a context i have tried requireContext(), this@..Activity, applicationContext, activity.context, and all the possibilities to get the context Here is the 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)
}

the logcat error

java.lang.IllegalStateException: Fragment Fragment3{3131d71} (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)
1 Answers

It looks like the problem is that the old Fragment is still there and is still getting the Firebase callback after it has been detached from the old Activity. You'll need to remove the Firebase callbacks when the old Fragment is detached/destroyed.

This is why you see this problem when you return back to TabbarActivity but not when you start the app for the first time.

Related