Search code examples
androidkotlinretrofit

Kotlin App Crash if back button pressed during fetching API


So i have the problem that the App will crash if the Back button is pressed during fetching service in a fragment. Currently I'm using Retrofit Library to do the service calling tasks. Below is the code snippet of the fragment :

ProductStockOutletListFragment.kt

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    (activity as AppCompatActivity).supportActionBar?.title = "Product List"

    binding = DataBindingUtil.inflate(inflater, R.layout.fragment_product_stock_outlet_list, container, false)

    //Show Progressbar While loading data
    binding.progressBar.visibility = View.VISIBLE

    //Apply layout manager
    binding.rvOutletList.layoutManager = LinearLayoutManager((activity as AppCompatActivity))

    NetworkConfig().getOutletListService()
        .getOutlets()
        .enqueue(object : Callback<OutletListPOJODataClasses> {

            override fun onFailure(call: Call<OutletListPOJODataClasses>, t: Throwable) {

                if(call.isCanceled){
                    Toast.makeText((activity as AppCompatActivity), "Request Aborted", Toast.LENGTH_SHORT).show()
                }else{
                    Toast.makeText((activity as AppCompatActivity), t.localizedMessage, Toast.LENGTH_SHORT).show()
                }

            }

            override fun onResponse(
                call: Call<OutletListPOJODataClasses>,
                response: Response<OutletListPOJODataClasses>
            ) {
                binding.progressBar.visibility = View.GONE
                binding.rvOutletList.adapter = response.body()?.let { OutletListAdapter(it, this@ProductStockOutletListFragment) }

                Toast.makeText((activity as AppCompatActivity), "Data retrieved!", Toast.LENGTH_SHORT).show() //It points out this line. This is where the error happened.
            }

        })

    // Declare that this fragment has menu
    setHasOptionsMenu(true)

    // Set action bar title to "Outlet List"
    (activity as AppCompatActivity).supportActionBar?.title = "Outlet List"

    return binding.root
}

If back button is pressed, it'll crash and return the error

kotlin.TypeCastException: null cannot be cast to non-null type androidx.appcompat.app.AppCompatActivity

The error pointed out at the below line at OnResponse()

Toast.makeText((activity as AppCompatActivity), "Data retrieved!", Toast.LENGTH_SHORT).show()

Am I missing something ? Or maybe this is a lifecycle-related problem ? Let me know if there's anything Unclear.

Edit : As requested, This is the full error log. enter image description here


Solution

  • The exception is because the activity you used in Toast becomes null when you backpress (fragment is destroyed) but the api response is received later and toast is executed.

    So just add a null check before toasting:

    if(activity!=null){
        Toast.makeText((activity as AppCompatActivity), "Data retrieved!", Toast.LENGTH_SHORT).show()
    }